泛型类的内部类的问题

时间:2017-03-11 23:17:34

标签: java generics polymorphism

以下代码无法编译最后一行,即使最后一行编译好,而差异仅在通用类型中,似乎在其范围内。

谁能解释一下吗?我想这与擦除有关,但为什么倒数第二个语句编译好?

public class Main {
    public static class A {
        public class Inner {
        }
    }

    public static class B extends A {
        public class Inner {
        }
    }

    public static class Wrap<T extends A> {
        public Class<T.Inner> get(Class<T.Inner> cls) {
            return cls;
        }
    }

    public static void main(String... args) {
        Wrap<A> wa = new Wrap<>();
        Wrap<B> wb = new Wrap<>();
        // this compiles OK
        Class<A.Inner> ai = wa.get(A.Inner.class);
        // this fails
        Class<B.Inner> bi = wb.get(B.Inner.class);
    }
}

编译错误:

 /tmp$ javac -Xdiags:verbose Main.java
Main.java:24: error: method get in class Wrap<T> cannot be applied to given types;
        Class<B.Inner> bi = wb.get(B.Inner.class);
                              ^
  required: Class<Main.B.Inner>
  found: Class<Main.B.Inner>
  reason: argument mismatch; Class<Main.B.Inner> cannot be converted to Class<Main.B.Inner>
  where T is a type-variable:
    T extends Main.A declared in class Wrap
1 error

1 个答案:

答案 0 :(得分:3)

我无法解释java的必需/已找到的陈述,但在将T定义为T extends A时,T.Inner变为A.Inner

有多种可能的变化使其有效:

  • Inner
  • 中移除B
  • Inner的{​​{1}}定义为B并将get方法更改为extends A.Inner (使用Eclipse编译器工作,使用JDK&#39; s无效) javac的)
  • public <C extends T.Inner> Class<C> get(Class<C> cls)的{​​{1}}定义为Inner,并将get方法更改为B

如何更改它取决于您希望使用此类构造实现的目标。