首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >什么时候菱形语法在Java 8中不起作用?

什么时候菱形语法在Java 8中不起作用?
EN

Stack Overflow用户
提问于 2014-11-26 03:02:08
回答 1查看 13.6K关注 0票数 13

在Java7中,菱形语法并不总是在方法参数中工作,例如Why does the diamond operator not work for java.util.Collections methods in Java 7?。这个问题的答案提到Java 8中的目标类型推断修复了这个问题。

是否还有其他不能使用菱形语法的情况?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-27 05:09:31

菱形运算符不能总是在Java8中使用。在Java8 (JEP 101)中改进推理的最初计划有两个目标:

  • 在方法上下文中添加对方法类型参数推断的支持
  • 在链接调用中添加对方法类型参数推断的支持

只实现了第一个。借用JEP中的示例,考虑以下类:

代码语言:javascript
运行
复制
class List<E> {
   static <Z> List<Z> cons(Z head, List<Z> tail) { ... };
   E head() { ... }
}

在Java 8中,改进的方法上下文推断允许编译以下代码。在Java7中,它将失败,并显示错误expected List<Integer>, found List<Object>

代码语言:javascript
运行
复制
List<Integer> l = List.cons(42, new List<>());

但是,需要推断链式调用的示例仍然不适用于Java 8:

代码语言:javascript
运行
复制
Integer i = new List<>().head();

JSR 335的D部分包含了关于为什么在Java8中放弃了链式表达式推理的提示:

在允许对“链”的推断方面有一些兴趣:在a().b()中,将类型信息从b的调用传递到a的调用。这增加了推理算法的复杂性,因为必须在两个方向上传递部分信息;只有当a()的返回类型的擦除对于所有实例化(例如列表)都是固定的时,它才有效。由于目标类型不容易派生,因此此功能不能很好地适应poly模型;但也许将来可以通过额外的增强来添加它。

还有一些不能使用钻石的人为的例子。

如果有bug,这在jdk8u25之前不能用javac编译。(参见JDK-8029002)

代码语言:javascript
运行
复制
class Test {
  class C<T extends C<T>> {}
  void m() {
    C<?> i = new C<>();
  }
}

代码语言:javascript
运行
复制
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),可能会影响使用菱形运算符的代码。如果使用菱形运算符,则下面的示例需要几分钟才能编译完成。

代码语言:javascript
运行
复制
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<>()));
  }
}
票数 21
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27134626

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档