当我直接将Arrays.asList()赋值给变量时,为什么会出现AssertionError?

28

我正在尝试理解Java 10中的局部变量类型推断

  1. 以下代码在编译和运行期间都可以正常工作:

    List list1 = Arrays.asList(1L, 2.0F, "3");
    var list2 = list1;
    
  2. 然而,这一行会抛出编译错误:

    var list3 = Arrays.asList(1L, 2.0F, "3");
    

    错误:java: java.lang.AssertionError: 意外的交叉类型: java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>

    我不太明白为什么第二种情况是错的,而第一种情况却没有问题。因为我预期编译器会推断出list1的类型并将list2list3视为相同的类型。谢谢。


2
@AmanChhabra 可能是 IntelliJ... - Eugene
@Eugene 不,我在 JShell 上尝试过了,它运行得很好。 - Aman Chhabra
4
@AmanChhabra 我的观点是,OP的问题与IntelliJ有关。 - Eugene
3
请注意,OP的代码与您在评论中提供的代码有所不同:"var list3"与"List list3"。意思是一样的。 - Code-Apprentice
8
在第一个例子中,您使用了“原始类型”(raw type)List。当然,当您使用var时,编译器将不会推断出“原始类型”List。请参考此链接:https://dev59.com/m3E85IYBdhLWcg3wdDIM - Holger
显示剩余2条评论
2个回答

24

这是Java 10编译器中的一个错误:https://bugs.openjdk.java.net/browse/JDK-8199910

仅在使用-g标志调用javac时才会重现。

可能的解决方法:

  1. 不要使用-g标志
    • 如果您使用的是IDEA:设置→构建、执行、部署→编译器→Java编译器→取消选中“生成调试信息”
  2. 不要使用带有交集类型的var(使用显式类型):
    • List<Object> list = Arrays.asList(1L, 2.0F, "3");
    • var list = Arrays.<Object> asList(1L, 2.0F, "3");
  3. 使用具有自己编译器的Eclipse

更新:

该错误已在JDK 10.0.2中修复。


2
谢谢。在取消“生成调试信息”后,它可以工作。 - hoan

12

这是openjdk的一个bug,参见此链接:

Javac应该跳过LocalVariableTypeTable属性中的不可指定类型。


8
我相信这个问题在 JDK 10 中也会被修复。如果他们不将如此关键的错误向后移植,那将是糟糕的事情。 - ZhekaKozlov
2
谢谢大家,我确认它可以在使用 java version "10" 2018-03-20 Java(TM) SE Runtime Environment 18.3 (build 10+46) 的jshell中运行。 - hoan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接