为什么不能指定我<! - ?将Type - >扩展为<type>?</type>

时间:2014-06-09 08:11:39

标签: java generics type-conversion extends bounded-wildcard

以下陈述:

URLClassLoader ucl = (URLClassLoader) ClassLoader.getSystemClassLoader();
Class<URLClassLoader> uclc = ucl.getClass();

失败并显示错误:

Type mismatch: cannot convert from Class<capture#2-of ? extends URLClassLoader> to Class<URLClassLoader>

为什么我需要演员?

我发现了几个帖子,解释了为什么你不能反过来(将T分配给a),但那种(有点)是显而易见的。

注意:我在eclipse Luna下编码,所以我不知道它是否是Luna Quirk,或者是否有一些我在仿制药中真的不了解的东西。

2 个答案:

答案 0 :(得分:8)

Covariance vs contravariance vs invariance

  • Class<? extends URLClassLoader> 不变

结果,

Class<? extends URLClassLoader> 不是Class<URLClassLoader>

的子类型

在Java中,变量可以包含相同类型或子类型的实例的引用。

因此,

Class<URLClassLoader> uclc = ucl.getClass();

无效

另一方面,

Class<? extends URLClassLoader> uclc = ucl.getClass();

有效

答案 1 :(得分:1)

  

为什么不能指定我&lt;?扩展类型&gt;到&lt; Type&gt;?

因为实际上<? extends Type><Type>的超类型!让我们按照规范进行操作。

4.10.2 Subtyping among Class and Interface Types

  

给定泛型类型声明C&lt; F 1 ,...,F n &gt;,参数化类型C&lt; T 1的直接超类型,...,T <子>名词&GT;是以下所有:

     
      
  • C&lt; S 1 ,...,S n &gt;,其中S i 包含T i
  •   

4.5.1. Type Arguments of Parameterized Types

  

类型参数T 1 被认为包含另一个类型参数T 2 ,写成T 2 &lt; = T 1 ,如果由T 2 表示的类型集合可证明是T 1 表示的类型集的子集,则在下面的自反和传递闭包下规则:

     
      
  • T&lt; =?延伸T
  •   

因此,我们知道,由于? extends URLClassLoader包含URLClassLoaderClass<? extends URLClassLoader>Class<URLClassLoader>的超类型。

由于narrowing reference conversion中不允许assignment context,因此会发生编译错误。

另请注意,这意味着允许反向分配:

Class<URLClassLoader> concrete = URLClassLoader.class;
Class<? extends URLClassLoader> wildcard = concrete;