United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6318240 Creation of array of inner class of an enclosing wildcard type doesn't work
JDK-6318240 : Creation of array of inner class of an enclosing wildcard type doesn't work

Details
Type:
Bug
Submit Date:
2005-08-31
Status:
Closed
Updated Date:
2012-04-06
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
tools
OS:
windows_xp
Sub-Component:
javac
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0
Fixed Versions:

Related Reports
Relates:
Relates:

Sub Tasks

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

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
                                     
2006-10-25
SUGGESTED FIX

Webrev of changes http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=6318240
See also attachment 6318240.tar.gz.
                                     
2006-10-26
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);
                                     
2006-10-26
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.
                                     
2006-10-26



Hardware and Software, Engineered to Work Together