首页 新闻 会员 周边

java stream泛型不填写会导致类型擦除

0
悬赏园豆:15 [已解决问题] 解决于 2021-06-25 10:31
List list = new ArrayList();
        list.add("aaa");

        list.stream().map(a->a.toString())
                .filter(a->a)

如上代码,如果list不加泛型,会导致stream后的每个transform类型都无法识别,全部变成了Object类型,例如filter算子里面,a应该是个String类型。

这种现象产生的深层次的原因是什么,求解释

问题补充:
List<Object> list = new ArrayList();
list.stream().map(a->a.toString())
                .filter(a->a)

List list = new ArrayList();
list.stream().map(a->a.toString())
                .filter(a->a)

的结果不一致。第一段代码,在map之后,其后面的stream元素的类型已经转成String了,
而在下面一段代码里面,所有的stream元素类型都是Object,无论算子如何操作,都无法改变其类型,类型被擦除

周周周文阳的主页 周周周文阳 | 初学一级 | 园豆:10
提问于:2021-06-24 10:52
< >
分享
最佳答案
-1

因为List不加泛型你可以将他理解为

List<Object> list = new ArrayList<>();

泛型其实就是个语法糖,泛型的存在是保证让你编译期可以约束你要添加的元素是同一种类型。
在运行期是没有泛型这个概念的,编译期后你以为的 List<T> 已经变成 List了,里面所有涉及泛型的函数都会被
擦成Object类型。所以在你不指定泛型的时候List就是运行期的List,add函数接收的就是Object类型对象。
也因为多态的特性,你可以放进去String类型,因为String是Object的子类。

收获园豆:15
刷最大的碗 | 菜鸟二级 |园豆:279 | 2021-06-24 16:02

谢谢。但是您没有回答我想问的问题,我的问题已经补充了,您的回答也可以补充

周周周文阳 | 园豆:10 (初学一级) | 2021-06-24 16:09

@周周周文阳:
补充下回答 :
map这个函数的作用是将给定函数应用到集合每一个元素中,并返回一个新的流。注意返回的这个新的流,因为首先你创建了泛型集合,在你调用stream的.map的时候泛型为Object。因为lambda表达式将集合元素全部变为String类型.在最终返回新Stream流时,泛型R变成String类型了

刷最大的碗 | 园豆:279 (菜鸟二级) | 2021-06-24 17:54

@刷最大的碗: 你说的是对的。但是我的疑问是不加泛型时,返回的Stream流为什么,泛型R为什么还是Object

List list = new ArrayList();
list.stream().map(a->a.toString())
                .filter(a->a)
周周周文阳 | 园豆:10 (初学一级) | 2021-06-24 17:57

@周周周文阳: 因为你不加泛型你后面调用的stream().map()这些都没有泛型了

刷最大的碗 | 园豆:279 (菜鸟二级) | 2021-06-24 18:02

@刷最大的碗: 那岂不是跟你说的语法糖矛盾了吗

周周周文阳 | 园豆:10 (初学一级) | 2021-06-24 18:04

@周周周文阳: 没矛盾啊 你不加泛型就是运行期的真实面貌了 只不过标注的泛型T其实就是变成Object了 至于你所看到的那是编译期编译器上你看到的,是方便你理解。你就记住只要不加泛型就没有泛型这个概念,泛型只是约束

刷最大的碗 | 园豆:279 (菜鸟二级) | 2021-06-24 18:10
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册