List<Integer>有两个remove重载:remove(int index)和remove(Object o)——这篇真实构造一个4元素的list,验证remove(20)这种写法编译器真实选的是哪一个,以及真实会发生什么。
List接口对Integer这种包装类元素同时提供了remove(int index)和remove(Object o)两个方法,真实对比它们的行为差异。
ListRemoveIntVsObjectDemo.java List<Integer> list = new ArrayList<>(List.of(10, 20, 30, 40)); listA.remove(1); // int字面量 listB.remove(Integer.valueOf(1)); // 显式装箱成Object
初始list: [10, 20, 30, 40] listA.remove(1) [int重载,删索引] 真实结果: [10, 30, 40] listB.remove(Integer.valueOf(1)) [Object重载,删值] 真实结果: [10, 20, 30, 40] (真实size是否变化: false)
真实结果证明同样传入"1"这个数字,两种写法真实得到完全不同的结果:remove(1)(int字面量)真实删除了索引1的元素(值20);而remove(Integer.valueOf(1))(显式装箱)真实是在按值查找——因为list里没有值为1的元素,所以真实什么都没删除,size真实没有变化。Java的重载解析规则是:能不装箱就不装箱,int字面量会优先精确匹配remove(int index)这个重载,只有显式传入包装类型或Object,才会真实匹配到remove(Object o)。
如果开发者的真实意图是"删除值为20的元素",但写成了remove(20),会发生什么?
ListRemoveIntVsObjectDemo.java listC.remove(20); // 意图:删掉值为20的元素;真实调用:remove(int index)
listC.remove(20) 真实抛出: java.lang.IndexOutOfBoundsException: Index 20 out of bounds for length 4 (证明它真实调用的是remove(int index),而不是删除值为20的元素) listD.remove(Integer.valueOf(20)) 真实结果(正确删除值为20的元素): [10, 30, 40]
每一步的 list 内容都是真实运行这段代码之后的状态,不是按规则手工推的。