JAVA泛型中通配符到底是什么东西

发布于 2022-09-06 22:50:49 字数 457 浏览 11 评论 0

比如有这样一个泛型类

public class Gen<T>{
    
}

然后在其他类中有这样一个方法

public void showKeyValue(Gen gen){}

public void showKeyValue(Gen<?> gen){}

还有,为什么Gen<Object>和Gen<String>是同一种类(Gen<Object>.Class = Gen<String>.class)
但是Gen<String>却不能指向Gen<Object>的引用(Gen<Object> gen = new Gen<String>会报错)
这两种方法有什么区别吗,如果没有,那么这个的意义在哪呢?
新手,希望能有大神解释下

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

西瓜 2022-09-13 22:50:49

官方文档 中有写这个问题. 这里做一把搬运工, 大致翻译如下:

无界通配符(unbounded wildcard)在以下两种场景下使用:

  • 如果你在函数中需要调用 Object 类中的方法, 比如 toString().
  • 如果代码不依赖于具体的类型. 典型的例子是 Class<?>: Class<T> 类中的多数方法都不需要知道 T 的类型.

关于第一种情况的例子, 有如下方法, 用来打印 List 中的元素信息:

public static void printList(List<Object> list) {
    for (Object elem : list)
        System.out.println(elem + " ");
    System.out.println();
}

但上面的函数输出的是一串内存地址, 而不是 toString() 方法的内容: 它无法正确打印 List<Integer>, List<String> 等列表的值, 因为这些列表并非 List<Object> 的子类型. 使用 List<?> 可以解决这个问题:

public static void printList(List<?> list) {
    for (Object elem: list)
        System.out.print(elem + " ");
    System.out.println();
}

因为 List<A>List<?> 的子类型, 所以上面函数可以正常打印任何类型的列表:

List<Integer> li = Arrays.asList(1, 2, 3);
List<String>  ls = Arrays.asList("one", "two", "three");
printList(li);
printList(ls);

注意: List<Object>List<?> 也有区别: 前者可插入任何 Object 子类, 后者只能插入 null, 原因见 官方文档中的通配符使用指南.


刚刚看到你还有第二个问题. Gen<Object> gen = new Gen<String> 会报错, 这个问题很好理解: gen.add(new Object()) 这种操作是非法的, 因为新添加的 Object 实例未必是 String 实例.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文