-
Bug
-
Resolution: Unresolved
-
P4
-
5.0, 7, 8
The text in 8.8.7.1 does not account for the possibility that an outer instance of an object might have a parameterized type. There is a clear error when a super constructor invocation is qualified. The unqualified case needs clarification (in general, the meaning of "method", "class", and "field" need clarification where generics are involved).
See 6886402 for an example and related compiler bug.
Comments on specific bits of the text:
"Let S be the direct superclass of C": this is fine, as long as it is understood that the class Outer<X>.S and Outer<Y>.S are different classes, just as List<String>.add and List<Object>.add are different methods. Otherwise, S must be a type. (A problem with the first interpretation is that, where Sub extends Sup and Sup declares C, the types Sub.C and Sup.C are "the same", per 4.3.4. It could be problematic to have two classes be considered distinct even though the corresponding types are "the same". On the other hand, it makes no sense talking about the "members of class S", as we do often in the spec, without having an implicit understanding that S is uniquely identified by *both* its declaration and the type in which it is referenced.)
"let O be the immediately lexically enclosing class of S": here, we need a type, not just a class -- the parameters of O matter. This mapping from classes to their lexically-enclosing types is not well-defined. Where O1<T> declares S, O2 extends O1<String>, and C extends O2.S, should the type O be O2 or O1<String>?
"it is a compile-time error if the type of p is not O or a subclass of O" -> "type of p is not *a subtype of* O"
"or of a superclass or superinterface thereof ... let O be the innermost lexically enclosing class of which S is a member": this is contradictory -- if S is hidden by another declaration, as anticipated by the first clause, then O may be undefined.
"Let O be the innermost lexically enclosing class of which S is a member": It needs to be clear that "S" means a particular parameterization of the enclosing classes of the declaration of S, and "is a member" means that the class O<T>.S has the same declaration and same corresponding type arguments as S.
This same problem arises in 15.9.2, in both the discussion of C's enclosing class and S's enclosing class. This is assuming it is legal to say "new Outer<X>.Inner()" and "new Outer<X>.Inner() {}" (these are rejected by javac's parser, but I'm not sure the spec disallows it).
See 6886402 for an example and related compiler bug.
Comments on specific bits of the text:
"Let S be the direct superclass of C": this is fine, as long as it is understood that the class Outer<X>.S and Outer<Y>.S are different classes, just as List<String>.add and List<Object>.add are different methods. Otherwise, S must be a type. (A problem with the first interpretation is that, where Sub extends Sup and Sup declares C, the types Sub.C and Sup.C are "the same", per 4.3.4. It could be problematic to have two classes be considered distinct even though the corresponding types are "the same". On the other hand, it makes no sense talking about the "members of class S", as we do often in the spec, without having an implicit understanding that S is uniquely identified by *both* its declaration and the type in which it is referenced.)
"let O be the immediately lexically enclosing class of S": here, we need a type, not just a class -- the parameters of O matter. This mapping from classes to their lexically-enclosing types is not well-defined. Where O1<T> declares S, O2 extends O1<String>, and C extends O2.S, should the type O be O2 or O1<String>?
"it is a compile-time error if the type of p is not O or a subclass of O" -> "type of p is not *a subtype of* O"
"or of a superclass or superinterface thereof ... let O be the innermost lexically enclosing class of which S is a member": this is contradictory -- if S is hidden by another declaration, as anticipated by the first clause, then O may be undefined.
"Let O be the innermost lexically enclosing class of which S is a member": It needs to be clear that "S" means a particular parameterization of the enclosing classes of the declaration of S, and "is a member" means that the class O<T>.S has the same declaration and same corresponding type arguments as S.
This same problem arises in 15.9.2, in both the discussion of C's enclosing class and S's enclosing class. This is assuming it is legal to say "new Outer<X>.Inner()" and "new Outer<X>.Inner() {}" (these are rejected by javac's parser, but I'm not sure the spec disallows it).
- relates to
-
JDK-6886402 Parameterized inner classes and subclassing
- Open
-
JDK-8030746 4.10: Define subtyping for inner classes of parameterized types
- Open
-
JDK-8157994 8.8.7.1: Account for an inherited supertype S
- Closed