为啥直接将 Arrays.asList() 分配给 var 时会出现 AssertionError?

Posted

技术标签:

【中文标题】为啥直接将 Arrays.asList() 分配给 var 时会出现 AssertionError?【英文标题】:Why am I getting an AssertionError when assigning Arrays.asList() to var directly?为什么直接将 Arrays.asList() 分配给 var 时会出现 AssertionError? 【发布时间】:2018-09-08 13:52:52 【问题描述】:

我正在尝试理解 Java 10 中的 local variable type inference。

    以下代码在编译和运行时完美运行:

    List list1 = Arrays.asList(1L, 2.0F, "3");
    var list2 = list1;
    

    但是,这一行会引发编译错误:

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

    Error:java: java.lang.AssertionError: Unexpected intersection type: java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>

我真的不明白为什么第二种情况是错误的,但不是第一种情况。因为我希望编译器会推断出list1 的类型并将list2list3 视为相同。提前致谢。

【问题讨论】:

我不认为你的问题是正确的,因为我尝试了这两个语句并正确执行:jshell> List list3 = Arrays.asList(1L, 2.0F, "3"); list3 ==> [1, 2.0, 3] jshell> List list1 = Arrays.asList(1, 2.0, "3"); list1 ==> [1, 2.0, 3] @AmanChhabra 可能是 IntelliJ... @AmanChhabra 我的意思是 OP 问题与 IntelliJ 有关 @AmanChhabra 请注意,OP 的代码与您在评论中输入的代码不同:var list3List list3 在第一个示例中,您使用的是raw type List。当然,当你使用var时,编译器不会推断原始类型 List... 【参考方案1】:

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

只有在使用 -g 标志调用 javac 时才会复制它。

可能的解决方法:

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

UDPATE:

该错误已在JDK 10.0.2 中修复。

【讨论】:

谢谢。在我取消选中“生成调试信息”后它可以工作。【参考方案2】:

这是openjdk的一个bug,见this:

Javac 应该跳过 LocalVariableTypeTable 中的不可表示类型 属性

【讨论】:

我相信这也将在 JDK 10 中得到修复。如果他们不向后移植这样一个严重的错误,那就太疯狂了。 谢谢大家,我确认使用 jshell 和 java version "10" 2018-03-20 Java(TM) SE Runtime Environment 18.3 (build 10+46) 可以正常工作

以上是关于为啥直接将 Arrays.asList() 分配给 var 时会出现 AssertionError?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 Arrays.asList() 返回自己的 ArrayList 实现

为啥Java里的Arrays.asList不能用add和remove方法

使用Arrays.asList的优点和缺点

Arrays.asList()用法梳理

Arrays.asList

Java-Arrays类-Arrays.asList()方法详解