java.lang.Class泛型和通配符

塔维安·巴恩斯(Tavian Barnes)

为什么以下代码无法编译?

interface Iface<T> { }

class Impl<T> implements Iface<T> { }

class TestCase {
    static Class<? extends Iface<?>> clazz = Impl.class;
}

错误是

java:不兼容的类型:java.lang.Class<Impl>无法转换为java.lang.Class<? extends Iface<?>>

但我不明白为什么不捕获通配符。

Radiodef

这里的子类型关系为:

          Class<? extends Iface>
           ╱                  ╲
Class<? extends Iface<?>>   Class<Impl>

(我在回答“无法从转换List<List>List<List<?>>”中解释了这一点。)

因此本质上它不会编译,因为它是横向转换。

如果可能的话,您可以执行我在那边描述的转换:

(Class<? extends Iface<?>>)(Class<? extends Impl>)Impl.class

如果您无法进行转换,则可能只需要处理raw bound即可Class<? extends Iface>主要由于警告而令人讨厌,但它打开了发生错误的可能性:

interface Iface<T> {
    void accept(T a);
}

class Impl2 implements Iface<String> {
    public void accept(String a) { }
}

class TestCase {
    static Class<? extends Iface> clazz = Impl2.class;

    public static void main(String[] args) throws Exception {
        // throws ClassCastException
        clazz.newInstance().accept(new Object());
    }
}

不太可能发生,但是我想这取决于您在做什么。


我倾向于认为这是Java类型系统的问题。

  • 可能应该有一个特殊的规则,即类型实参? extends T<?>包含类型实参? extends T,例如Class<? extends T>a转换为Class<? extends T<?>>从定义子类型(T是的超类型T<?>的现有方式的角度来看,这没有任何意义,但从类型安全的角度来看,这是有意义的。

  • 或者,例如List.class应该是Class<List<?>>而不是Class<List>

  • 还是比我聪明的人可以想到的其他一些聪明的东西。

ClassCastException我上面描述的有趣的事情是它是完全人为的。实际上,使用未经检查的演员表阻止它会引起警告。

我想这只是Java泛型尚未完成的一个信号。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

泛型Java通配符和子类型

来自分类Dev

Java泛型,对象和通配符的差异和说明

来自分类Dev

静态和非静态与泛型和Java中的通配符

来自分类Dev

Java-泛型和通配符与接口与实现

来自分类Dev

具有复合键和通配符的Java泛型

来自分类Dev

Java泛型中的通配符

来自分类Dev

Java泛型中的通配符

来自分类Dev

Java泛型:定义泛型类时的通配符和类型参数语法

来自分类Dev

带有泛型JSON的杰克逊无法构造java.lang.Class的实例

来自分类Dev

Java泛型.class

来自分类Dev

Java泛型通配符与类型化泛型用法

来自分类Dev

Java泛型:覆盖泛型方法,通配符速记?

来自分类Dev

Java泛型:不兼容的通配符捕获

来自分类Dev

无法设置Java泛型通配符边界

来自分类Dev

从Scala调用Java通配符泛型方法

来自分类Dev

Java泛型-通配符的目的(下限除外)?

来自分类Dev

Java HashMap使用通配符嵌套泛型

来自分类Dev

Java泛型查询(上界通配符)

来自分类Dev

Java泛型,未绑定通配符<?>与<Object>

来自分类Dev

Java泛型中的边界扩展通配符

来自分类Dev

Java HashMap使用通配符嵌套泛型

来自分类Dev

Java泛型中的边界扩展通配符

来自分类Dev

Java泛型的双通配符参数化(嵌套通配符)

来自分类Dev

Java泛型-使用上限和下限通配符进行迭代

来自分类Dev

Java Arraylist。使用泛型和通配符创建可重用的方法

来自分类Dev

Java泛型,类型擦除,通配符和功能<?...>产生不兼容的类型

来自分类Dev

由于java.lang.Object而导致的泛型不能转换为[Ljava.lang.Object

来自分类Dev

Java泛型和模板

来自分类Dev

Java泛型和流