关于Java泛型下限用法:?超级T

时间:2017-10-29 06:26:52

标签: java generics

我试图在一定深度上理解下界通配符的用法。我正在尝试编写一个通用方法copy,它将一个List的内容复制到另一个<T> void copy(List<T> dest, List<? extends T> src) 。我想出了这个方法签名:

<T> void copy(List<? super T> dest, List<? extends T> src)

我认为这个签名可以全面解决所有情况。但是,我在Java Collections类中看到方法签名是这样的:

List<? super T> dest

我不明白为什么他们使用List<T> dest而不是clientsAllocation[j] = input.privateFIFOName; 。他们的签名是否有一些额外的灵活性?

2 个答案:

答案 0 :(得分:5)

没有明确的证人类型,没有实际区别。

如果没有指定Eran所做的类型见证,两种方法之间的灵活性没有差异。

基本上,使用? super T而不是T只是一种风格差异,但这是更好的做法,可以通过应用一些好的代码原则来看出:

  • 明确意图:? super T更明确地显示dest应采用的类型。
  • Modularity:您根本不需要查看src上的类型约束来了解dest可以采用的类型。
  • Producer Extends, Consumer Super (PECS):生产者参数(下面的“in”)应该使用extends而消费者参数(下面的“out”)应该使用super关键字。

Java tutorials也建议使用? super T(他们甚至使用copy函数):

  

出于本讨论的目的,将变量视为提供两个函数之一是有帮助的:

     

“In”变量
  “in”变量向代码提供数据。想象一下copy方法有两个参数:copy(src, dest)src参数提供要复制的数据,因此它是“in”参数。

     

“退出”变量
  “out”变量保存数据以供其他地方使用。在copy示例copy(src, dest)中,dest参数接受数据,因此它是“out”参数。

     

在决定是否使用通配符以及适合使用哪种类型的通配符时,可以使用“in”和“out”原则。以下列表提供了遵循的准则:

     

通配符指南:

     
      
  • “in”变量使用上限有限的通配符定义   extends关键字。
  •   
  • “out”变量定义为下限   通配符,使用super关键字。
  •   

答案 1 :(得分:1)

以下是一个例子:

以下代码段使用签名<T> void copy(List<? super T> dest, List<? extends T> src)传递编译,但不能使用签名<T> void copy(List<T> dest, List<? extends T> src)

YourClass obj = new YourClass ();
List<HashMap<String,String>> lhm = new ArrayList<>();
List<Map<String,String>> lm = new ArrayList<>();
obj.<HashMap<String,String>>copy (lm,lhm);