我在使用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可看成树叶,赋值时是生成一份新的