JDK-6318240 : Creation of array of inner class of an enclosing wildcard type doesn't work
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows_xp
  • CPU: x86
  • Submitted: 2005-08-31
  • Updated: 2012-04-06
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b03Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0-b64)
Java HotSpot(TM) Client VM (build 1.5.0-b64, mixed mode, sharing)

java version "1.6.0-ea"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.6.0-ea-b40)
Java HotSpot(TM) Client VM (build 1.6.0-ea-b40, mixed mode, sharing)


ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows XP [version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
Currrent javac implementation doesn't permit
in its parser to create an array of a inner class that have
a generic enclosing class.

see Foo example after :

inner = new Foo<?>.Inner[10];
or
inner = new Foo<Object>.Inner[10];

can't be parsed by the compiler.

This problem come from comments on the Scott Violet weblog :
(http://weblogs.java.net/blog/zixle/archive/2005/08/should_we_gener_1.html)
and i don't see why it's not syntactically and semantically correct.

Reading the JL3 grammar, it seems legal :
new Foo<?>.Inner[10] is :
'new'
ClassOrInterfaceType
    (ClassOrInterfaceType(TypeName('Foo') TypeArguments('<?>')) '.'
Identifier('Inner'))
DimExprs('[10]')

so it's syntactically legal.

I think it semantically valid for the same reason that
new List<?>[10] is valid.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile the Foo class.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
it compiles.
ACTUAL -
it doesn't compile.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
C:\eclipse\workspace\java-patch\src>javac Foo.java
Foo.java:11: '(' or '[' expected
        inner = new Foo<?>.Inner[10];
                          ^
1 error


---------- BEGIN SOURCE ----------
public class Foo<T> {
    private T t;
    private Foo<?>.Inner[] inner;
    public Foo(T t) {
        this.t = t;
        inner = new Foo<?>.Inner[10];
    }
    private class Inner {
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
use a raw type instead :

public class Foo<T> {
    private T t;
    private Foo<?>.Inner[] inner;
    public Foo(T t) {
        this.t = t;
        inner = new Foo.Inner[10];
    }
    private class Inner {
    }
}

Comments
EVALUATION I agree that 'new Foo<Object>.Inner[10]' must be rejected because Foo<Object>.Inner is not reifiable, as required by JLS 15.10.
26-10-2006

SUGGESTED FIX Index: j2se/src/share/classes/com/sun/tools/javac/parser/Parser.java --- /tmp/geta19538 2006-10-25 20:09:47.000000000 -0700 +++ /tmp/getb19538 2006-10-25 20:09:47.000000000 -0700 @@ -1346,6 +1346,15 @@ checkGenerics(); t = typeArguments(t); } + while (S.token() == DOT) { + int pos = S.pos(); + S.nextToken(); + t = toP(F.at(pos).Select(t, ident())); + if (S.token() == LT) { + checkGenerics(); + t = typeArguments(t); + } + } mode = oldmode; if (S.token() == LBRACKET) { JCExpression e = arrayCreatorRest(newpos, t);
26-10-2006

SUGGESTED FIX Webrev of changes http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=6318240 See also attachment 6318240.tar.gz.
26-10-2006

EVALUATION This is a bug. As the submitter points out, the syntactic forms are: new ClassOrInterfaceType DimExprs Dimsopt new ClassOrInterfaceType Dims ArrayInitializer See http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.10 ClassOrInterfaceType includes type arguments so there is a strong argument for having the parser execpt them. However, the compiler must reject examples like this: new Foo<Object>.Inner[10] Because it is a compile time error if the ClassOrInterface does not denote a reifiable type. See http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.7
25-10-2006