如果你不懂,可以不看的问题背景:
Java编译器会阻止对声明类型为List<? extend T>
的集合的add操作;会阻止对声明类型为List<? super T>
的集合的get操作。会有类似add(capture<? extend T>) can not be applied to T
的错误提示为什么编译器要这么做?
咦,你穿越到了CS的世界,你知道这个世界上有一个只能存放一种身份的人或者拥有共同身份的人的黑盒,有一个入口和出口,黑盒上贴了一张纸条,向外面的你提示了黑盒中的人的类型,当然据说黑盒中会有惊喜。
你还知道这个世界有下面几种身份的人:平民、警察、匪徒,警察和匪徒是拥有武器的平民,他们的身份高低相等但都大于平民,但是穿越到这个世界这么久,你还没有见过一个平民。
而且城里面还流传着一个可怕的都市传说:由于警察和匪徒手持不同的武器,当你把警察和匪徒放到黑盒的同一个空间中,他们就会Boom!甚至由于从小接受不同的教育,如果警察或者匪徒穿上对立身份的衣服见到阳光,他们也会立刻Boom!天啊,太可怕了!这些疯子!你无奈的摇摇头。有一天,别人给你一个黑盒,上面贴着一张纸条“里面的人的身份大于等于平民”。送礼的人传给你一句话:“盒子里面的人实在是太酷了,拥有顶级装备,而且每一个进入这个黑盒的人都会变得很酷”。作为一个无可救药的小人爱好虾者,你很纠结。里面可能有五种情况:只有警察、只有匪徒、有警察心的平民、有匪徒心的平民、或者两种平民混合。对于前两种情况,你只能塞对应的警察或者匪徒进去;对于后三种情况,你可以安心的放任意警察或者匪徒进去。看着一柜子的普通人偶,你有点心动,但问题是:在真正放进一个警察或者匪徒进去前,你永远不知道这个黑盒会不会Boom!为了防止发生薛定谔的悲剧,你发誓永远不往这个黑盒中塞东西。但是你抑制不住心中的好奇,希望把黑盒中的人都拿出来看看,为了不Boom,你只能用平民的方式把黑盒里的人拿出来,你安慰自己,至少能看看平民长什么样子吧。好吧,这是你在这个世界见到的第一个平民。
又过了一天,别人又给你一个黑盒,上面又贴着一张纸条“里面的人的身份小于等于平民”。送礼的人传给你一句话:“盒子里面有一个人身上或者装备上有财宝”。你很纠结,里面可能有三种情况:有警察心的平民、有匪徒心的平民、或者两者都有,根据上一次的坑爹经验,你已经知道平民倍受歧视,上面啥都没有;问题是你不知道里面具体的是警察还是匪徒,警察不可能变成匪徒拿出来,匪徒也不可能变成警察拿出来,否则就会Boom!是搏一搏?你知道你很怂,所以你艰难的把黑盒的出口用胶水封存了。想到这个黑盒把自己的心情搞得一团糟,你气愤的把上次取出来的平民人偶全部塞进黑盒,扔出窗外。
PS:编译器是非常怕死的,对于给出<? extend T>
、<? super T>
这种类型声明的集合,它基于“向上转型”的原则,用最安全的方式去处理。