United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
JDK-6486430 : Compiler fails to reject access to static member in parameterized type

Details
Type:
Bug
Submit Date:
2006-10-26
Status:
Closed
Updated Date:
2017-05-16
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
tools
OS:
generic
Sub-Component:
javac
CPU:
generic
Priority:
P4
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports
Relates:
Relates:
Relates:

Sub Tasks

Description
The compiler fails to reject this program:

public class Test<T extends Number> {
    Test<?>.Inner.InnerMost x = null;
    Test<Inner.InnerMost>.Inner.InnerMost y = null;
    private static class Inner<S> {
        private static class InnerMost {
        }
    }
}

                                    

Comments
EVALUATION

Notwithstanding my previous Evaluation, we have decided to forbid access to static types nested inside parameterized types, as per 6493167.
                                     
2006-11-14
EVALUATION

JLS 8.5 permits member types, including static member types, inside any class or interface declaration. The fact that a class or interface declaration is generic does not inherently forbid it from containing member types.

That is, the static type Test<...>.Inner<...>.InnerMost is explicitly defined as having no instance of Test<...>.Inner<...>. Therefore, it doesn't matter that we don't know the type arguments to Test and Inner.

I agree that it's inconvenient to reference InnerMost. Test<?>.Inner<?>.InnerMost is a possibility. Alternatively, InnerMost could be imported for unqualified use, because a static member type within a generic type declaration should be a valid target for static-import-on-demand. The intent of JLS 7.5.1 is that a type inside a generic type can be imported, under the generic type's erased name, so the following should be legal:
import static Test.*;
import static Test.Inner.*:
(Extra discussion in 7.5.4 would be worthwhile.)

Accessing a static member type within a generic type declaration does not seem as silly as 'new <HowdyDoody>Object[123]' in 6413682. It seems semantically harmless to say:
Test<?>.Inner.InnerMost x = null;
though it shouldn't parse because it should be:
Test<?>.Inner<?>.InnerMost x = null;

This is semantically wrong:
Test<Inner.InnerMost>.Inner.InnerMost y = null;
because Inner.InnerMost does not extend Number, as Test's type argument is required to do.
                                     
2006-10-26
SUGGESTED FIX

See 6318240 for webrev.
                                     
2006-10-26
SUGGESTED FIX

Index: j2se/src/share/classes/com/sun/tools/javac/comp/Check.java
--- /tmp/geta16827	2006-10-25 19:33:02.000000000 -0700
+++ Check.java	2006-10-25 19:31:46.000000000 -0700
@@ -829,14 +829,16 @@
             }
 	}
         public void visitSelectInternal(JCFieldAccess tree) {
-            // If this is a nested class, validate qualifying type.
-            if (tree.type.getEnclosingType().tag == CLASS)
+            if (tree.type.getEnclosingType().tag != CLASS &&
+                tree.selected.type.isParameterized()) {
+                // The enclosing type is not a class, so we are
+                // looking at a static member type.  However, the
+                // qualifying expression is parameterized.
+                log.error(tree.pos(), "cant.select.static.class.from.param.type");
+            } else {
+                // otherwise validate the rest of the expression
                 validate(tree.selected);
-
-            // Otherwise, check that the qualifying type is not parameterized
-            else if (tree.selected.type.isParameterized())
-                log.error(tree.pos(),
-                          "cant.select.static.class.from.param.type");
+            }
         }
 
 	/** Default visitor method: do nothing.
                                     
2006-10-26
EVALUATION

This is a bug.

It appears that comp/Check.Validator.visitSelectInternal fails to
recurse depending on the type of the enclosing class (which is NONE
for static nested classes).
                                     
2006-10-26



Hardware and Software, Engineered to Work Together