V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
pumpkin
V2EX  ›  问与答

关于一个 Java 泛型的问题

  •  
  •   pumpkin · 2016-12-23 17:37:05 +08:00 · 2022 次点击
    这是一个创建于 2898 天前的主题,其中的信息可能已经有所发展或是发生改变。

    由于 Java 泛型的擦除,经常会看到会给泛型加一个擦除的边界

    <T extends X>
    
    

    我想问的是:为什么不直接用多态来实现这种需求,这个擦除的边界不就相当于多态吗?

    7 条回复    2016-12-24 07:55:21 +08:00
    zhaohui318
        1
    zhaohui318  
       2016-12-23 17:53:27 +08:00   ❤️ 1
    看着题目眼熟,之前写过一片文章,可以参考一下

    http://garywzh.xyz/2016/06/10/Java%E7%9A%84%E9%9B%86%E5%90%88%E4%B8%8E%E6%B3%9B%E5%9E%8B/
    misaka19000
        2
    misaka19000  
       2016-12-23 17:54:52 +08:00 via Android
    @zhaohui318 很好,学习到了
    fwrq41251
        3
    fwrq41251  
       2016-12-23 18:56:20 +08:00 via Android
    关键词:协变
    incompatible
        4
    incompatible  
       2016-12-23 19:06:44 +08:00
    @zhaohui318 把 List<Dog>转换成一个 List<Animal>的最省事儿的方式:

    public List<Animal> convert(List<Dog> dogList) {
    return (List) dogList;
    }
    21grams
        5
    21grams  
       2016-12-23 19:28:38 +08:00
    这问题就相当于为什么用泛型不用多态
    SoloCompany
        6
    SoloCompany  
       2016-12-23 23:23:18 +08:00   ❤️ 4
    generic / covariant / invariant

    这几个概念建议都要看一下

    早期的 java 没有泛型,但有数组,而数组在 java 语言里面是定义为 covariant 的,也就是赋值相容的,这其实是一个错误,因为把一个 String[] 类型转换为 Object[] 没有任何警告,但以后的元素赋值可能会产生 ClassCastException

    Java 泛型的设计纠正了这个错误,是 invariant 的,也就是赋值不相容,你不能把 List<String> 直接当成 List<Object> 来用,但可以当做 List<? extends Object> 来用,自然而然, extends 和 super 关键字就是必须的了

    invariant 的泛型也给编程带来很多麻烦,因为无法进行类型转换(当然,因为 java 的泛型是擦除的,强制转换并且消除警告也总是有办法做到的)

    进一步的,如果你有看过 kotlin 的话,有专门章节介绍泛型, kotin 用 in / out 标记来代替了 extends / super , in / out 关键字不仅仅能修饰泛型参数类型,还能用来修饰泛型参数声明,配合不可变集合类型就能够支持 convariant 泛型(赋值相容)

    比如 kotlin 的 List 是不可变的,其接口声明是 interface List<out E>;
    意思是只能从里面取出来 E 类型的元素,不能保存
    那么 List<String> 和 List<Object> 就变得赋值相容了
    palmers
        7
    palmers  
       2016-12-24 07:55:21 +08:00 via iPhone
    这个在 think in java 中有解释 泛型是 1.5 才加进来的 为了多方妥协最后采用擦出边界这么一个折中的办法
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1270 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 17:55 · PVG 01:55 · LAX 09:55 · JFK 12:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.