Tav*_*nes 6 java generics bounded-wildcard
为什么以下代码无法编译?
interface Iface<T> { }
class Impl<T> implements Iface<T> { }
class TestCase {
static Class<? extends Iface<?>> clazz = Impl.class;
}
Run Code Online (Sandbox Code Playgroud)
错误是
java:不兼容的类型:
java.lang.Class<Impl>无法转换为java.lang.Class<? extends Iface<?>>
但我不明白为什么通配符不能捕获.
这里的子类型关系是:
\n\n Class<? extends Iface>\n \xe2\x95\xb1 \xe2\x95\xb2\nClass<? extends Iface<?>> Class<Impl>\nRun Code Online (Sandbox Code Playgroud)\n\n(我在对“无法从List<List>到转换List<List<?>>”的回答中对此进行了解释。)
所以本质上它不会编译,因为它是横向转换。
\n\n如果可能的话,你可以进行我在那里描述的转换:
\n\n(Class<? extends Iface<?>>)(Class<? extends Impl>)Impl.class\nRun Code Online (Sandbox Code Playgroud)\n\n如果您无法进行强制转换,那么您可能只需要处理原始有界Class<? extends Iface>. 这很烦人,主要是因为警告,但它也有可能出现错误:
interface Iface<T> {\n void accept(T a);\n}\n\nclass Impl2 implements Iface<String> {\n public void accept(String a) { }\n}\n\nclass TestCase {\n static Class<? extends Iface> clazz = Impl2.class;\n\n public static void main(String[] args) throws Exception {\n // throws ClassCastException\n clazz.newInstance().accept(new Object());\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n不太可能发生,但这取决于你在做什么,我想。
\n\n我倾向于认为这是 Java 类型系统的问题。
\n\n可能应该有一个特殊的规则,即类型参数? extends T<?>包含类型参数? extends T,例如 aClass<? extends T>转换为 a Class<? extends T<?>>。T从现有的子类型定义方式(是 的超类型)的角度来看,这是没有意义的,T<?>但从类型安全的角度来看,这是有意义的。
或者例如List.class应该是 aClass<List<?>>而不是 a Class<List>。
或者比我聪明的人也能想到其他一些聪明的事情。
我上面描述的有趣的事情ClassCastException是它完全是人为的。事实上,通过未经检查的强制转换来阻止它会导致警告。
我猜这只是 Java 中的泛型尚未完成的一个迹象。
\n| 归档时间: |
|
| 查看次数: |
842 次 |
| 最近记录: |