JDK-8059926 : java.lang.ClassCastException: [Ljava.lang.Number; cannot be cast to [Ljava.lang.Integer;
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 8u40,9
  • Priority: P4
  • Status: Resolved
  • Resolution: Not an Issue
  • Submitted: 2014-10-08
  • Updated: 2014-10-31
  • Resolved: 2014-10-14
Related Reports
Duplicate :  
Relates :  
Relates :  
Relates :  
Description
If this test case is compiled with javac:

interface Iface<T extends Number> {
    String m(T...t);
}

public class Test {
    public static void main(String[] args) {
        Iface<? super Integer> i = (Integer...a) -> "";
        String result = i.m(1);
    }
}

at execution time you will get:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Number; cannot be cast to [Ljava.lang.Integer;
	at Test$$Lambda$1/980546781.m(Unknown Source)
	at Test.main(Test.java:8)
Comments
I think the relevant spec paragraph is this (15.12.4.2): "If m is being invoked with k ��� n actual argument expressions, or, if m is being invoked with k = n actual argument expressions and the type of the k'th argument expression is not assignment compatible with T[], then the argument list (e1, ..., en-1, en, ..., ek) is evaluated as if it were written as (e1, ..., en-1, new |T[]| { en, ..., ek }), where |T[]| denotes the erasure (��4.6) of T[]." So, the key in this example is to establish what is T. The problematic call is this: i.m(1); where 'i' has type Iface<? super Integer>. Since the members of a wildcard-parameterized type are the members of its capture (see 4.5.2), let's capture the receiver type first: Iface<? super Integer> -> Iface<#CAP>, where Integer <: #CAP <: Number The type of 'm' when viewed as a member of the above captured type is: String m(#CAP...t) Meaning that our T (the varargs element type) is #CAP. The erasure of #CAP is the erasure of its upper bound (see 4.6), namely Number. Hence, the spec mandates that the above method call should be evaluated as: i.m(new Number[] { 1 });
30-10-2014

I would appreciate greatly if you could point to spec specifying this behavior.
28-10-2014

Note that the lambda in the test is a red herring. Behavior is the same with _any_ implementation of Iface (including a vanilla class) that specializes T.
14-10-2014

Javac is behaving according to the spec. Another issue is that the spec could be modified in order to make this code acceptable. Closing this issue.
14-10-2014