在Java7中,菱形语法并不总是在方法参数中工作,例如Why does the diamond operator not work for java.util.Collections methods in Java 7?。这个问题的答案提到Java 8中的目标类型推断修复了这个问题。
是否还有其他不能使用菱形语法的情况?
发布于 2014-11-27 05:09:31
菱形运算符不能总是在Java8中使用。在Java8 (JEP 101)中改进推理的最初计划有两个目标:
只实现了第一个。借用JEP中的示例,考虑以下类:
class List<E> {
static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
E head() { ... }
}在Java 8中,改进的方法上下文推断允许编译以下代码。在Java7中,它将失败,并显示错误expected List<Integer>, found List<Object>
List<Integer> l = List.cons(42, new List<>());但是,需要推断链式调用的示例仍然不适用于Java 8:
Integer i = new List<>().head();JSR 335的D部分包含了关于为什么在Java8中放弃了链式表达式推理的提示:
在允许对“链”的推断方面有一些兴趣:在a().b()中,将类型信息从b的调用传递到a的调用。这增加了推理算法的复杂性,因为必须在两个方向上传递部分信息;只有当a()的返回类型的擦除对于所有实例化(例如列表)都是固定的时,它才有效。由于目标类型不容易派生,因此此功能不能很好地适应poly模型;但也许将来可以通过额外的增强来添加它。
还有一些不能使用钻石的人为的例子。
如果有bug,这在jdk8u25之前不能用javac编译。(参见JDK-8029002)
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 ?新的类型推断实现还存在一个性能问题(JDK-8051946),可能会影响使用菱形运算符的代码。如果使用菱形运算符,则下面的示例需要几分钟才能编译完成。
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<>()));
}
}https://stackoverflow.com/questions/27134626
复制相似问题