【问题标题】:Java generics : wildcard extends class and include that classJava泛型:通配符扩展类并包含该类
【发布时间】:2018-05-21 17:19:37
【问题描述】:

假设你有这个变量:

Class<? extends AssetKey<?>> assetKeyClass;

那么我只能将assetKeyClass 设置为AssetKey 的子类类型。有没有办法做到这一点,并且允许 AssetKey 类类型本身?

像这样:

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

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

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

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

【问题讨论】:

  • 试试Class&lt;? extends AssetKey&gt;。您将收到有关使用原始类型的警告,但这是 AFAIK 唯一可能的方法。
  • Eclipse 会发出警告,但 Intellij 不会发出警告。嗯。天哪,你是对的!它有效,但我不知道为什么。

标签: java generics wildcard extends


【解决方案1】:

extends(或super)绑定始终包含绑定本身。

在您的情况下,问题是类文字,如 AssetKey.class,始终具有由该类的 非参数化 形式参数化的类型 Class。所以AssetKey.class 的类型为Class&lt;AssetKey&gt;。并且Class&lt;AssetKey&gt; 不是Class&lt;? extends AssetKey&lt;?&gt;&gt; 的子类型,因为原始类型 AssetKey 不是通配符参数化类型AssetKey&lt;?&gt; 的子类型。 (根据 Java 规则,一个类型的原始版本和参数化版本不是彼此的子类型。)

另一方面,TextureKey.class 具有类Class&lt;TextureKey&gt;Class&lt;? extends AssetKey&lt;?&gt;&gt; 的子类型,因为类型TextureKey(非泛型类)被声明为AssetKey&lt;Texture&gt; 的子类型,它是AssetKey&lt;?&gt; 的子类型。

如果你去掉通配符,只是将其声明为Class&lt;? extends AssetKey&gt; assetKeyClass;,它将起作用,因为AssetKey AssetKey 的子类型,因此Class&lt;AssetKey&gt; 是@ 的子类型987654341@.

【讨论】:

    【解决方案2】:

    正如Johannes Kuhn 评论的那样,答案是删除通配符,这样它是:

    Class<? extends AssetKey>.
    

    现在我只需要知道它为什么起作用。

    【讨论】:

      【解决方案3】:

      扩展一起使用

      Class<? extends AssetKey> assetKeyClass;
      
      // Subclass
      assetKeyClass = TextureKey.class;
      // Class
      assetKeyClass = AssetKey.class;
      

      超级一起使用

      Class<? super TextureKey> assetKeyClass ;
      
      // Subclass
      assetKeyClass = TextureKey.class;
      // Class
      assetKeyClass = AssetKey.class;
      

      【讨论】:

      • 这不是在回答我的问题。 Super 不能包含子类;只有超类。有没有办法包含类和子类?我需要它具有包容性。
      • 两种情况都有效并且代码编译。您可以将 extends 与超类 (AssetKey) 一起使用,或者将 super 与子类 (TextureKey) 一起使用。
      • 嗯,你的回答让我觉得我的问题不够清楚。
      猜你喜欢
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多