泛型微妙的差异

时间:2014-04-27 21:21:47

标签: java

  class P {

   }
  class Q extends P {

   }
  class R extends Q { 

   }
  class S extends R {

  }

  public class Manager {

    public static void main(String[] args) {

      X<? super R> x4 = null;
      x4.test(new S());
      x4.test(new R());
      x4.test(new P());//compile time error

     }
}

    class X<A> {
      void test(A obj) {

       }
    }

//表示R的R或超类,即P,Q或Object,但是为什么我在程序中指定的在线上得到编译时错误。

2 个答案:

答案 0 :(得分:4)

以下是JLS

中的一些规则
  

类型参数T1据说包含另一个类型参数T2,   写T2 <= T1,如果T2表示的类型集可证明是a   反射和反射下由T1表示的类型集的子集   传递性关闭以下规则(其中<:表示子类型   (§4.10)):

     

? super T <= ? super S if S <: T

     

? super T <= ?

     

? super T <= ? extends Object

     

T <= ? super T

符号

X<? super R> x4 = null;

使用通用通配符类型参数声明X,其下限为R

根据上述规则和变量声明,我们可以确定通配符涵盖RR本身的所有子类型。 SR的子类型,RRP不是R的子类型。

以下可能会产生混淆。你可以做到

X<? super R> x4 = new X<P>();

因为PR的超类。但是,当您想要使用类X的类型参数时,您只知道它必须至少是R

进一步阅读:

答案 1 :(得分:0)

您可以传递扩展R的对象,即R或S,但不能传递它的父对象。 R是任何传递实例的超类!