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