Summary
A code that names an inner class is erroneously classified as raw and as a result is erroneously rejected.
Problem
In the example that follows, javac determines erroneously that getter
has a raw type (G.Getter
). The type of getter
is deduced as the raw type Getters<T>.Getter
by javac which is clearly not since T
, the type parameter of Getters<T>
is not omitted. Since javac thinks that G
is raw, it raises the Object cannot be converted to T
message in the following example.
The question is whether it should be treated as raw or not in the scenario where the qualifying type is a type parameter, as in G.Getter
. In this case Getter
is an inherited member from the supertype Getters<T>
:
static abstract class Getters<T> {
abstract class Getter {
abstract T get();
}
}
static class Usage<T, G extends Getters<T>> {
public T test(G.Getter getter) {
return getter.get(); // incompatible types: Object cannot be converted to T
}
}
According to 4.8 Raw Types a "rare" type occurs when the inner is a partially raw type but the definition of Getter doesn't take any type variables, so this is not a case of a "rare" type. G.Getter describes a type with a qualifying type being a type parameter which is not raw and moreover there is an instantiation of its bound.
Not looking into the bounds of G is a compiler bug.
Solution
Fix javac to have the ability to traverse type bounds in such cases (isRaw).
Specification
We believe there are no changes needed in the specification but you can find linked the JDK-8030746; a currently open spec bug around the same area -- 4.10: Define subtyping for inner classes of parameterized types.
- csr of
-
JDK-8343580 Type error with inner classes of generic classes in functions generic by outer
-
- Resolved
-
- relates to
-
JDK-8030746 4.10: Define subtyping for inner classes of parameterized types
-
- Open
-