Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8359213

Inner classes of type parameters emitted as raw types in signatures

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Unresolved
    • Icon: P4 P4
    • 26
    • tools
    • None
    • source
    • minimal
    • The changes in this CSR will generally result in previously rejected code to be accepted by javac. There might be some corner cases where this change might affect overload resolution.
    • Language construct
    • SE

      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.

      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.

      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.

            abimpoudis Angelos Bimpoudis
            liach Chen Liang
            Vicente Arturo Romero Zaldivar
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: