为何List<int[]>可修改元素而List<Integer>不行?int[]是引用传递吗?
List<int[]>与List修改行为差异解析
先澄清一个误区:Java只有值传递
别被“引用传递”的说法误导——Java里所有参数传递都是值传递。对于数组、对象这类引用类型,传递的是「引用的副本」(也就是内存地址的拷贝),不是引用本身。
两种场景的底层逻辑
1. List<int[]>修改生效的原因
看这段代码:
List<int[]> res = List.of(new int[]{1, 2},new int[]{3,4}); int[] tempList = res.get(0); tempList[0] = 100;
int[]是引用类型,res.get(0)返回的是堆内存中数组对象的地址副本,tempList拿到这个副本后,和集合里存储的引用指向同一个数组对象。- 执行
tempList[0] = 100时,是通过这个引用副本直接操作堆里的数组元素——集合里存的本来就是指向这个数组的引用,所以数组内容变了,集合里的对应元素自然也跟着变。
2. List修改不生效的原因
再看这段代码:
List<Integer> list = List.of(1,2,3,4); Integer x = list.get(2); x = 200;
Integer是不可变包装类,一旦创建就没法修改内部的数值。list.get(2)返回的是指向Integer(3)的引用副本,x拿到后和集合里的引用指向同一个对象。但x = 200不是修改原Integer(3)的内容,而是新建了一个Integer(200)对象,让x转而指向这个新对象——原集合里的引用依然指向Integer(3),所以集合内容完全没变化。- 补充:哪怕用可变的
ArrayList替代List.of()的不可变集合,结果还是一样,因为问题根源不是集合能不能改,而是你根本没碰集合里的引用,只是给变量x换了个指向的对象。
核心结论
int[]是引用类型,你修改的是它指向的堆内存里的数组内容,所以集合能体现变化;Integer不可变,你所谓的“修改”其实是重新赋值了变量的引用,和原集合里的对象无关;- Java始终是值传递,引用类型传递的是引用的副本,不是引用本身。
内容的提问来源于stack exchange,提问作者tanvexr
相关产品推荐
相关产品推荐

