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 Availabitlity Release.

To download the current JDK release, click here.
JDK 7
7 b03Fixed
Related Reports
Relates :  
Relates :  
Relates :  
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