gpt4 book ai didi

java.lang.Class 泛型和通配符

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:20:54 24 4
gpt4 key购买 nike

为什么下面的代码编译不通过?

interface Iface<T> { }

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

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

错误是

java: incompatible types: java.lang.Class<Impl> cannot be converted to java.lang.Class<? extends Iface<?>>

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

最佳答案

这里的子类型关系是:

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

(我在对 'Cannot convert from List<List> to List<List<?>> ' 的回答中对此进行了解释。)

所以基本上它不会编译,因为它是横向转换。

如果可能的话,你可以做我在那边描述的转换:

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

如果您不能进行转换,那么您可能只需要处理原始有界 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>转换为 Class<? extends T<?>> .从定义子类型的现有方式(TT<?> 的父类(super class)型)的角度来看,这没有意义,但从类型安全的角度来看,这是有意义的。

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

  • 或者比我聪明的人能想到的其他聪明的东西。

关于 ClassCastException 的有趣之处我上面描述的是它完全是人为的。事实上,使用未经检查的转换来阻止它会导致警告。

我猜这只是 Java 中的泛型尚未完成的标志。

关于java.lang.Class 泛型和通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30090242/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com