| Other |
|---|
| tbd_majorUnresolved |
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
Given the following declarations:
abstract class Animal<T extends Animal<T>> {
public abstract T bestFriend();
public abstract Iterable<T> friends();
}
abstract class Dog extends Animal<Dog> {}
The capture of the following is specified to trigger a compiler error, per 5.1.10:
Animal<? extends Dog> a; // bound of capture var is glb(Dog, Animal<CAP>)
"It is a compile-time error if, for any two classes (not interfaces) Vi and Vj, Vi is
not a subclass of Vj or vice versa."
Actual javac behavior is to allow it, producing (apparently) an intersection of two different class types, 'Dog & Animal<CAP>'. These leads to arbitrary implementation-specific type checking behavior when members are looked up, e.g., in:
a.bestFriend().friends()
Two possible resolutions:
1) Enhance capture so that it does not produce an intersection of different class types, for example by inferring that 'capture(Animal<? extends Dog>) = Animal<Dog>' (because we know that a type like Animal<Poodle> is not in bounds).
2) Decide that the type Animal<? extends Dog> is malformed and require javac to enforce the restriction.
(Whether the conclusion is (1) or (2), similar reasoning could apply in the case of a final class, like Class<? extends String>. However, in that case there's nothing wrong with simply allowing the type as is without any special accommodations.)