Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么时候钻石语法在Java8中不起作用?_Java - Fatal编程技术网

什么时候钻石语法在Java8中不起作用?

什么时候钻石语法在Java8中不起作用?,java,Java,在Java7中,菱形语法并不总是在方法参数中起作用,例如。这个问题的答案提到Java8中的目标类型推理解决了这个问题 是否还有其他无法使用菱形语法的情况?在Java 8中不能始终使用菱形运算符。Java 8()中改进推理的最初计划有两个目标: 在方法上下文中添加对方法类型参数推断的支持 添加对链接调用中方法类型参数推断的支持 只有第一种方法得到了实施。借用JEP中的示例,考虑下面的类: class List<E> { static <Z> List<Z&g

在Java7中,菱形语法并不总是在方法参数中起作用,例如。这个问题的答案提到Java8中的目标类型推理解决了这个问题


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

在Java 8中不能始终使用菱形运算符。Java 8()中改进推理的最初计划有两个目标:

  • 在方法上下文中添加对方法类型参数推断的支持
  • 添加对链接调用中方法类型参数推断的支持
只有第一种方法得到了实施。借用JEP中的示例,考虑下面的类:

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<>()));
  }
}