以下代码在IntelliJ和Eclipse中编译良好,但JDK编译器1.8.0_25抱怨.一,代码.
import java.util.function.Predicate;
public abstract class MyStream<E> {
static <T> MyStream<T> create() {
return null;
}
abstract MyStream<E> filter(MyPredicate<? super E> predicate);
public interface MyPredicate<T> extends Predicate<T> {
@Override
boolean test(T t);
}
public void demo() {
MyStream.<Boolean> create().filter(b -> b);
MyStream.<String> create().filter(s -> s != null);
}
}
Run Code Online (Sandbox Code Playgroud)
javac 1.8.0_25的输出是:
MyStream.java:18: error: incompatible types: incompatible parameter types in lambda expression
MyStream.<Boolean> create().filter(b -> b);
^
MyStream.java:18: error: incompatible types: bad return type in lambda expression
MyStream.<Boolean> create().filter(b -> b); …Run Code Online (Sandbox Code Playgroud) 我接受,由于下限通配符,这个谓词不应该接受String没有显式转换的超类。[ 1 , 2 ] 这个问题是关于 lambda 参数列表中的类型安全实施。鉴于第二个块编译失败,为什么第一个块可以在没有警告的情况下编译?似乎在第一种情况下,尽管 lambda 的参数声明CharSequence被强制转换String为满足谓词的边界约束。
Predicate<? super String> predicate1 = (CharSequence c)
-> c.toString().length() > 2 ;
System.out.println(predicate1.test("foo")); // compiles
Run Code Online (Sandbox Code Playgroud)
Predicate<? super String> predicate2 = (CharSequence c)
-> c.toString().length() > 2 ;
System.out.println(predicate2.test((CharSequence)"foo")); // capture error
Run Code Online (Sandbox Code Playgroud)
error: method test in interface Predicate<T> cannot be applied to given types;
out.println(predicate2.test((CharSequence)"foo"));
^
required: CAP#1
found: CharSequence
reason: argument mismatch; CharSequence cannot be converted to CAP#1
where T is a type-variable:
T …Run Code Online (Sandbox Code Playgroud) 我知道我们无法在列表中添加扩展边界类型的元素。但我仍然不确定为什么java编译器不允许这样做。因为编译器可以很容易地检查添加的新元素是否是泛型类型的子类型。有人可以帮我解决这个问题吗?