Compiler bug involving vararg of length 0?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Fri Mar 22 09:35:42 PDT 2013


This works in JDK 8/lambda (even if using -source 7). In order to 
support lambda inference I did several inference-related cleanups, and 
it looks like I got rid of some bugs in the process ;-)

There has been a long outstanding issue with javac incorrectly using 
partially inferred signatures with varargs call - this seems to be the 
problem you are sseeing: since  E cannot be inferred from the arguments, 
JDK 7's javac would see that E is still uninferred after the first 
inference round. Therefore the array is created with a type that is the 
erasure of E - Object.

Now the compiler correctly waits until E is instantiated - which means 
it will create an array whose type is the erasure of List<String>.

P.S.
The Eclipse compiler has always created the right array type (List, not 
Object).

Maurizio

On 22/03/13 15:46, Zhong Yu wrote:
> The following code looks type safe, and compiles fine (jdk7u2b11)
>
>      @SafeVarargs
>      static <E> E[] newArray(int length, E... array)
>      {
>          return Arrays.copyOf(array, length);
>      }
>
>      public static void main(String[] args)
>      {
>          List<String>[] array = newArray(4);
>      }
>
> but at runtime it throws
>
>      java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast
> to [Ljava.util.List;
>
> Apparently, a new Object[0] is passed in as the vararg. Should that be a bug?
>
> If the type argument is explicitly provided
>
>          List<String>[] array = Test.<List<String>>newArray(4);
>
> no runtime exception. But shouldn't it be equivalent to the inferred case?
>
> Zhong Yu




More information about the compiler-dev mailing list