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

关于Java泛型的下限用法:?超级T,java,generics,Java,Generics,我试图深入了解下限通配符的用法。我正在尝试编写一个通用方法copy,它将一个列表的内容复制到另一个列表。我想出了这个方法签名: <T> void copy(List<T> dest, List<? extends T> src) void copy(List dest,List以下是一个示例: 下面的代码段通过编译并带有签名无效副本(List如果没有显式类型见证,则没有实际区别。 在没有像Eran那样指定类型见证的情况下,这两种方法在灵活性上没有区别 本质上

我试图深入了解下限通配符的用法。我正在尝试编写一个通用方法
copy
,它将一个
列表的内容复制到另一个
列表。我想出了这个方法签名:

<T> void copy(List<T> dest, List<? extends T> src)
void copy(List dest,List以下是一个示例:


下面的代码段通过编译并带有签名
无效副本(List如果没有显式类型见证,则没有实际区别。

在没有像Eran那样指定类型见证的情况下,这两种方法在灵活性上没有区别

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

  • 明确的意图:
    ?super T
    更明确地显示了
    dest
    应该采用的类型
  • :您根本不需要查看
    src
    上的类型约束,就可以知道
    dest
    可以采用哪些类型
  • :生产者参数(“下面的in”)应使用
    extends
    ,而消费者参数(“下面的out”)应使用
    super
    关键字
还建议使用
?super T
(他们甚至使用
复制功能):

在本讨论中,将变量视为提供以下两个函数之一是有帮助的:

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

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

在决定是否使用通配符以及什么类型的通配符合适时,可以使用“输入”和“输出”原则。以下列表提供了要遵循的准则:

通配符准则:

  • “in”变量使用上界通配符定义,使用
    扩展
    关键字
  • “out”变量定义为一个下限 通配符,使用
    super
    关键字

为了避免HTML吃掉泛型,您可以在内联代码周围加上反标记。上面的代码段通过了编译并带有两个签名。只是在Eclipse中检查了它。@user496934奇怪。我也在Eclipse上测试了这一点,得到了参数化方法copy(List,List@user496934你打电话给obj.copy(lm,lhm)了吗
或只是
对象复制(lm、lhm)
?编造这样一个示例很容易,但它完全不现实。我仍然很好奇它有什么实际用途。但这只是因为您指定了一个显式类型见证,它不是其中一个案例的正确类型见证。这并不能反驳两个声明接受相同的可能类型集的说法不使用类型证人时的论点。这个问题是。我认为展示所有案例的例子特别有说服力。(因为悬赏,不能像傻瓜一样接近。)@里弗:可能最好用mod标志来说明这是一个复制品,而不是回答它。@Makoto后来发现了这个复制品
<T> void copy(List<? super 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);