CSR :
|
|
Relates :
|
|
Relates :
|
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` which is clearly not, since `T`, the type parameter of `Getters<T>` is not omitted. javac thinks that `G` is raw and raises the `Object cannot be converted to T` message in the following example. In this example `Getter` is simply 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 } } ``` Not looking into the bounds of `G` is a compiler bug. A symmetrical situation occurs when there is a type application either explicitly or implicitly qualified and the enclosing type is not fully recalculated, for example the compiler crashes in the following two snippets. ``` class A<T> { protected class B<V> {} public static <T, M extends A<T>> void f(Object g) { @SuppressWarnings("unchecked") M.B<?> mapping = (M.B<?>) g; // explicitly qualified type application } } ``` ``` class A<T> { class B<W> { public T rett() { return null; } } } class C extends A<String> { static class D { { B<?> b = null; // implicitly qualified type application String s = b.rett(); } } } ``` The last examples are related to JDK-8357472. Solution -------- javac has the necessary functionality to normalize qualified type paths. Taken from the comment in Attr: ``` // class Tree<A> { class Visitor { ... } } // class PointTree extends Tree<Point> { ... } // ...PointTree.Visitor... // // Then the type of the last expression above is // Tree<Point>.Visitor. ``` The compiler performs the necessary traversal while calculating the qualifying type path of `PointTree.Visitor` with the type `Tree<Point>.Visitor`. In that case `PointTree` is a concrete class. The solution fixes the cases where the prefix of the path is not only a concrete class but a type parameter with a bound. In our case the correct type is: `Getters<T>.Getter`. The corresponding issue appears in the visitor method for parameterized types, in Attr, as well. 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.
|