我的类结构如下:
interface Z {}
interface Y extends Z {}
interface X extends Y {}
private static class A<T extends Z> {}
private static class B<T extends Y> extends A<T> {}
private static class C extends B<X> {}
为什么第一个有效而第二个无效?
private Class<? extends A<? extends Z>> clazz = C.class; // valid
private Class<? extends A<? extends Z>> clazzb = B.class; // error: Type mismatch: cannot convert from Class<TEST.B> to Class<? extends TEST.A<? extends TEST.Z>>
我想这是因为在第二个示例中Y
的类型不清楚,但是您如何能够澄清它?
谢谢
答案 0 :(得分:0)
简单地说;否,您不能绑定Class
literal分配,因为B<T>
是泛型类型,即您可以:
Class<? extends A<? extends Z>> clazzb = B<X>.class; // illegal statement
// OR
Class<? extends A<? extends Z>> clazzb = B<W>.class; // assuming W is a sub-type of X
因为只有一个类文字(就字节码(运行时)和语言约束(编译时)而言): B.class
并且由于编译器将无法知道T
类的类型参数B
属于哪种类型,因此不允许分配。
下面的赋值声明是合法的(可以编译):
Class<? extends A> clazzb = B.class;
但带有警告,并且完全符合 Generic Class and Type Parameters Java Language Specification 。
我已经多次见过 Java 特定模式,开发人员使用通用实用程序方法 inferring 解决其编译器类型检查,以使其返回类型与分配的参考类型:
<!-- language : lang-java -->
@SuppressWarnings("unchecked")
public static <T> Class<T> inferType(Class<?> clazz) {
return (Class<T>) clazz;
}
那么您将能够执行曾经被禁止的:
Class<? extends A<? extends Z>> clazzb = generify(B.class);
请注意,这应该是不推荐的解决方法。为了让您更加确定,请在下面编写的 非常令人困惑的 语句如下:
Class<C> clazzb = generify(A.class);
乍看之下,这应该行不通,但是毕竟您将为类引用分配类文字。