什么时候钻石语法在Java8中不起作用?
在Java7中,菱形语法并不总是在方法参数中起作用,例如。这个问题的答案提到Java8中的目标类型推理解决了这个问题什么时候钻石语法在Java8中不起作用?,java,Java,在Java7中,菱形语法并不总是在方法参数中起作用,例如。这个问题的答案提到Java8中的目标类型推理解决了这个问题 是否还有其他无法使用菱形语法的情况?在Java 8中不能始终使用菱形运算符。Java 8()中改进推理的最初计划有两个目标: 在方法上下文中添加对方法类型参数推断的支持 添加对链接调用中方法类型参数推断的支持 只有第一种方法得到了实施。借用JEP中的示例,考虑下面的类: class List<E> { static <Z> List<Z&g
是否还有其他无法使用菱形语法的情况?在Java 8中不能始终使用菱形运算符。Java 8()中改进推理的最初计划有两个目标:
- 在方法上下文中添加对方法类型参数推断的支持
- 添加对链接调用中方法类型参数推断的支持
class List<E> {
static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
E head() { ... }
}
类列表{
静态列表cons(Z头,列表尾){…};
E头(){…}
}
在Java8中,改进的方法上下文推断允许编译以下内容。对于Java 7,它将失败,出现错误expected List,found List
List l=List.cons(42,newlist());
但是,需要对链式调用进行推理的示例仍然不能用于Java 8:
Integer i = new List<>().head();
Integer i=new List().head();
的D部分包含了一个关于为什么Java 8放弃链式表达式推断的提示:
人们对允许推理“链”产生了一些兴趣:在a().b()中,将类型信息从b的调用传递到a的调用。这又增加了推理算法的复杂性,因为部分信息必须双向传递;它仅在所有实例化(例如List)的a()返回类型的擦除都已修复时起作用。由于目标类型不容易派生,因此此功能不太适合多边形表达式模型;但是,也许有了更多的增强功能,它可以在将来添加
还有一些更人为的例子,钻石不能被使用 如果有bug,那么在jdk8u25之前不会使用javac编译。(见附件)
类测试{
类C{}
void m(){
C i=新的C();
}
}
错误:不兼容类型:无法推断Test.C的类型参数
C i=新的C();
^
原因:推断类型不符合上限
推断:Test.C
上限:Test.C,Test.C
其中CAP#1是一个新类型变量:
第1章将Test.C从捕获?
新的类型推断实现还存在性能问题(),可能会影响使用菱形运算符的代码。如果使用菱形运算符,则编译以下示例需要几分钟
class Test {
<T> T and(T a, T b) { return null; }
class C<T> {}
void g(String s) {}
void g(Object s) {}
void m() {
g(
and(
and(
and(
and(
and(
and(
and(new C<>(),
new C<>()),
new C<>()),
new C<>()),
new C<>()),
new C<>()),
new C<>()),
new C<>()));
}
}
类测试{
T和(ta,tb){returnnull;}
类C{}
void g(字符串s){}
void g(对象s){}
void m(){
g(
及(
及(
及(
及(
及(
及(
和(新的C(),
新的C()),
新的C()),
新的C()),
新的C()),
新的C()),
新的C()),
新C());
}
}
不是菱形运算符,但Java 8对lambda返回类型的类型推断有一个缺点:加1;有了这样的答案,你会超过乔恩·斯基特。
class Test {
class C<T extends C<T>> {}
void m() {
C<?> i = new C<>();
}
}
error: incompatible types: cannot infer type arguments for Test.C<>
C<?> i = new C<>();
^
reason: inferred type does not conform to upper bound(s)
inferred: Test.C<CAP#1>
upper bound(s): Test.C<Test.C<CAP#1>>,Test.C<CAP#1>
where CAP#1 is a fresh type-variable:
CAP#1 extends Test.C<CAP#1> from capture of ?
class Test {
<T> T and(T a, T b) { return null; }
class C<T> {}
void g(String s) {}
void g(Object s) {}
void m() {
g(
and(
and(
and(
and(
and(
and(
and(new C<>(),
new C<>()),
new C<>()),
new C<>()),
new C<>()),
new C<>()),
new C<>()),
new C<>()));
}
}