JDK-6486430 : Compiler fails to reject access to static member in parameterized type
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2006-10-26
  • Updated: 2017-05-16
  • 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.
7 b03Fixed
Related Reports
Relates :  
Relates :  
Relates :  
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 {

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

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.

SUGGESTED FIX See 6318240 for webrev.

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.

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).