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 :  
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)
I think the relevant spec paragraph is this ( "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 });

I would appreciate greatly if you could point to spec specifying this behavior.

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.

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.