目录
1. 问题概述
1.1 测试
1.2 结果
2. ArrayList和Arrays.ArrayList
1. 问题概述
最近忙着写论文很久没更新了,趁现在有时间简单记录一下最近遇到的一个坑。
对于Java中的List<>类型的对象,按我以前理解是引用传递,但有一点要注意,就是在调用方法里面如果直接将一个新的List对象赋值于该方法参数,会导致变成值传递,因为这个操作直接修改了方法参数的引用地址,无论怎么修改都无法影响到调用方法的对象。
1.1 测试
先看看下面的代码,简单来说就是通过handleList方法更新sourceList。
public static void handleList1(List<String> sourceList) {
System.out.println("handleList1");
List<String> tempList = new ArrayList<>();
for(String item: sourceList) {
if(item.equals("EEEEE")) {
// can't change sourceList directly
tempList.add("E");
} else {
tempList.add(item);
}
}
sourceList = tempList;
}
public static void handleList2(List<String> sourceList) {
System.out.println("handleList2");
List<String> tempList = new ArrayList<>();
for(String item: sourceList) {
if(item.equals("EEEEE")) {
// can't change sourceList directly
tempList.add("E");
} else {
tempList.add(item);
}
}
sourceList.clear();
sourceList.addAll(tempList);
}
通过以下方法测试:
public static void main(String[] args) {
// 1
List<String> sourceList = new ArrayList<String>(){{add("A"); add("B"); add("C"); add("D");add("EEEEE");}};
handleList1(sourceList);
System.out.println(sourceList);
// 2
sourceList = new ArrayList<String>(){{add("A"); add("B"); add("C"); add("D");add("EEEEE");}};
handleList2(sourceList);
System.out.println(sourceList);
}
1.2 结果
上面可以发现handleList1方法并没有成功修改sourceList的值,因为重新为sourceList赋予了新的地址,永远不会改变原来地址空间的sourceList。
但其实如果idea用的是专业版的话就可以直接发现这个bug,但是当时用的社区版没提示一着急就踩坑了。
2. ArrayList和Arrays.ArrayList
顺便提一下,因为上面的要求需要修改List的内容,line26不能直接修改for循环的sourceList内容,
同时如果List是Arrays.ArrayList的实例,那么不支持add(); clear(); addAll();这些操作,
不然都会报UnsupportedOperationException。
所以如果需要将数组转成List,可以这样:
List list = new ArrayList<>(Arrays.asList("A", "B", "C"))
更多方式可以参考:List操作add,clear,addall