我在使用C/C++的時候,心裏總是非常踏實,因爲我知道我所寫的就是機器所運行的。我掌控一切。但Java/Golang則屬於一種封裝後的語言,在其背後幫我們做了很多。一方面這方便了我們,另外一方面卻使得我們心裏不踏實,因爲有時搞不清語言在背後會怎麼做。
Java的等號賦值操作有時候讓我迷惑,比如在集合和類的情形,是值拷貝,還是指針傳遞?這裏測試一下,明白其思路,讓心裏踏實。
我把集合和類看成樹的節點,經常會分叉。我把最終的數值看成樹的葉子。以下是測試及結果。
//==========第一個測試:節點是List,樹葉是String=============
LinkedList<String> al = new LinkedList<String>();
al.add( "test");
String ns = al.get(0);
ns = "test000";
Log. d("ListTest", "ns=new: "+al.get(0));
//輸出 ns=new: test
//原始樹葉不變
//說明取得的是複製的樹葉,原來的樹葉不變
//==========第二個測試:增加類這個節點=============
class Person {
String name;
};
LinkedList<Person> students = new LinkedList<Person>();
Person zs = new Person();
zs. name = "zhangsan" ;
students.add(zs);
Person ww = students.get(0);
ww. name = "wangwu" ;
Log. d("ListTest", "students.get(0).name:" + students.get(0).name);
//輸出 students.get(0).name:wangwu
//原始樹葉被修改
//也即複製了類這個節點,新節點依然指向原來的樹葉
//==========第三個測試:類中的String是樹葉================
String lisi = students.get(0).name;
lisi = "lisi";
Log. d("ListTest", "students.get(0).name:" + students.get(0).name);
//仍然輸出 students.get(0).name:wangwu
//原始值不變
//說明取得的是複製的樹葉,原始樹葉不變
//==========第四個測試:類中有類================
class Addr{
String addr;
}
class Person2 {
String name;
Addr a;
};
Addr aa = new Addr();
aa. addr = "shanghai" ;
Person2 zhaoliu = new Person2();
zhaoliu. name = "zhaoliu" ;
zhaoliu. a = aa;
Addr bb = zhaoliu. a;
bb. addr = "guangzhou" ;
Log. d("ListTest", "zhaoliu.a.addr:" + zhaoliu.a .addr );
//輸出 zhaoliu.a.addr:guangzhou
//原始樹葉被改變
//複製了類這個節點,新節點依然指向原來的樹葉
//==========第五個測試================
ArrayList<LinkedList<String>> alll = new ArrayList<LinkedList<String>>();
LinkedList<String> ll = new LinkedList<String>();
alll.add(ll);
ll.add( "abc");
LinkedList<String> ll2 = alll.get(0); //測試get(0)是複製和傳指針
ll2.set(0, "def");
Log. d("ListTest", "alll.get(0).get(0):" + alll.get(0).get(0));
//輸出 alll.get(0).get(0):def
//原始樹葉被修改
//複製了List這個節點,新節點依然指向原來的更下一級節點或樹葉
//結論:
// List或類對象可以看成節點,內含指針,賦值即傳遞指針
// 但指針依舊指向下級節點或原始樹葉
// String可看成樹葉,賦值時是生成一份新的