Java 8 Java 8中的编译器错误,Java 6中没有错误,为什么?
我有以下代码:Java 8 Java 8中的编译器错误,Java 6中没有错误,为什么?,java-8,compiler-errors,guava,iterable,java-6,Java 8,Compiler Errors,Guava,Iterable,Java 6,我有以下代码: import java.util.ArrayList; import java.util.List; import com.google.common.base.Function; import com.google.common.collect.FluentIterable; class B { } class C extends B { } class D { } class Test { void test() { List<B> l
import java.util.ArrayList;
import java.util.List;
import com.google.common.base.Function;
import com.google.common.collect.FluentIterable;
class B { }
class C extends B { }
class D { }
class Test {
void test() {
List<B> lb = new ArrayList<B>();
List<C> lc = new ArrayList<C>();
Iterable<B> it = lb == null ? lc : lb; // a
FluentIterable.from(lb == null ? lc : lb).transform(new Function<B, D>() { // b
@Override
public D apply(B b) {
return null;
}
});
}
}
import java.util.ArrayList;
导入java.util.List;
导入com.google.common.base.Function;
导入com.google.common.collect.fluentiable;
B类{}
类C扩展了B{}
类D{}
课堂测试{
无效测试(){
List lb=new ArrayList();
List lc=new ArrayList();
Iterable it=lb==null?lc:lb;//a
FluentIterable.from(lb==null?lc:lb).transform(新函数(){//b
@凌驾
公开申请(B){
返回null;
}
});
}
}
在Java 8下,line//b给出了以下编译器错误:
不兼容的类型。找到:'java.util.List',必需:'java.util.ListTL;DR在Java 8中更改了类型推断的语言规范。
行//a是一个编译时错误,因为列表不能分配给Iterable类型的变量。如果是,那么您可以编译以下不健全的代码
List<C> listOfC = new ArrayList<C>();
Iterable<B> listOfB = listOfC; // if this were allowed it would be bad
listOfB.add(new B()); // ...because now my list of C's has a B in it
C reallyAB = listOfC.get(0); // ...and now i have an object of type B in a variable of type C
reallyAB.methodThatsDefinedOnAC(); // ...and crash
List listOfC=new ArrayList();
Iterable listOfB=listOfC;//如果这被允许,那将是糟糕的
添加(新的B());/。。。因为现在我的C名单上有一个B
C reallyAB=listOfC.get(0);/。。。现在我有一个类型为B的对象,在一个类型为C的变量中
reallyAB.MethodsDefinedOnAC();/。。。和崩溃
检测不合理的赋值对于编译器来说很简单,因为//a行上的变量具有显式类型
行//b更复杂,因为该方法具有泛型类型参数,因此编译器必须在检查参数的同时推断方法的类型。随着Java8的发布,围绕如何推断类型参数的规则发生了显著的变化,Java8将Lambdas引入到语言中,目的是在大多数情况下改进类型推断
这里详细分析了三元运算符现在无法满足泛型类型约束的原因:
规范之间的不兼容性记录在此jdk错误中:
您可以通过提供显式类型来克服规则中的限制。您可以将表达式结果分配给变量,并将变量传递到调用中,也可以强制转换表达式
void test() {
List<B> lb = new ArrayList<B>();
List<C> lc = new ArrayList<C>();
FluentIterable.from((List<? extends B>)(lb == null ? lc : lb)).transform(new Function<B, D>() { // b
@Override
public D apply(B b) {
return null;
}
});
}
void测试(){
List lb=new ArrayList();
List lc=new ArrayList();
可流动的((列表行a
应为Iterable@Holger谢谢,我不太明白为什么Java 8在第b行出现错误,而Java 6在第b行没有出现错误。你能给我一些提示吗?我也不明白。规则非常复杂,并且由于合并了目标类型而发生了更改。但是由于没有可用的目标类型在这一点上,我希望它的行为类似于Java6。
void test() {
List<B> lb = new ArrayList<B>();
List<C> lc = new ArrayList<C>();
FluentIterable.from((List<? extends B>)(lb == null ? lc : lb)).transform(new Function<B, D>() { // b
@Override
public D apply(B b) {
return null;
}
});
}