EVALUATION
Notwithstanding my previous Evaluation, we have decided to forbid access to static types nested inside parameterized types, as per 6493167.
|
|
|
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).
|
|
|
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.
|
|
|
SUGGESTED FIX
See 6318240 for webrev.
|
|
|
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.
|
|
|
|