28

I'm trying to understand local variable type inference in Java 10.

  1. The code below works perfectly during compilation and runtime:

    List list1 = Arrays.asList(1L, 2.0F, "3");
    var list2 = list1;
    
  2. However, this line throws a compilation error:

    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<?>>

I don't really understand why the 2nd case is wrong but not the 1st case. Because I expect the compiler would infer the type of list1 and treat list2 and list3 the same. Thanks in advance.

hoan
  • 1,058
  • 8
  • 13

2 Answers2

24

This is a bug in Java 10 compiler: https://bugs.openjdk.java.net/browse/JDK-8199910

It is only reproduced when javac is called with a -g flag.

Possible workarounds:

  1. Do not use the -g flag
    • If you use IDEA: Settings → Build, Execution, Deployment → Compiler → Java Compiler → Uncheck "Generate Debugging Info"
  2. Do not use var with intersection types (use explicit types):
    • List<Object> list = Arrays.asList(1L, 2.0F, "3");
    • var list = Arrays.<Object> asList(1L, 2.0F, "3");
  3. Use Eclipse which has its own compiler

UDPATE:

The bug was fixed in JDK 10.0.2.

ZhekaKozlov
  • 36,558
  • 20
  • 126
  • 155
12

This is a bug of openjdk, see this:

Javac should skip non-denotable types in the LocalVariableTypeTable attribute

xingbin
  • 27,410
  • 9
  • 53
  • 103
  • 8
    I believe this will be fixed in JDK 10 too. It will be crazy if they do not backport such a critical bug. – ZhekaKozlov Mar 29 '18 at 15:19
  • 2
    Thank guys, I confirm that it works by using jshell with `java version "10" 2018-03-20 Java(TM) SE Runtime Environment 18.3 (build 10+46)` – hoan Mar 30 '18 at 08:40