Java 泛型:通配符扩展 class 并包含 class

Java generics : wildcard extends class and include that class

假设你有这个变量:

Class<? extends AssetKey<?>> assetKeyClass;

那我只能把assetKeyClass设置成AssetKey的subclass类型了。有没有办法做到这一点加上允许 AssetKey class 类型本身?

像这样:

// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;

编辑: 忘记显示一些 class 代码:

public class AssetKey<T> {
// ...
}

public class TextureKey extends AssetKey<Texture> {
// ...
}

一起使用扩展

Class<? extends AssetKey> assetKeyClass;

// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;

使用super

Class<? super TextureKey> assetKeyClass ;

// Subclass
assetKeyClass = TextureKey.class;
// Class
assetKeyClass = AssetKey.class;

正如 Johannes Kuhn 评论的那样,答案是删除通配符,使其成为:

Class<? extends AssetKey>.

现在我只需要知道它为什么有效。

extends(或super)绑定总是包含绑定本身。

你的问题是 class 文字,如 AssetKey.class,总是具有 非参数化 [=43] 参数化的类型 Class =] 的形式 class。所以 AssetKey.class 的类型是 Class<AssetKey>Class<AssetKey> 不是 Class<? extends AssetKey<?>> 的子类型,因为 原始类型 AssetKey 不是通配符参数化类型 AssetKey<?> 的子类型。 (根据 Java 规则,类型的原始版本和参数化版本不是彼此的子类型。)

另一方面,TextureKey.class 有 class Class<TextureKey> Class<? extends AssetKey<?>> 的子类型,因为类型 TextureKey(非泛型 class)被声明为 AssetKey<Texture> 的子类型,AssetKey<Texture>AssetKey<?>.

的子类型

如果你放弃通配符,只将它声明为 Class<? extends AssetKey> assetKeyClass;,它将起作用,因为 AssetKey AssetKey 的子类型, 因此 Class<AssetKey>Class<? extends AssetKey>.

的子类型