前言
最近在看關(guān)于java的一些東西,但在網(wǎng)上查詢資料時(shí)發(fā)現(xiàn)好多人都關(guān)于java到底是值傳遞還是引用傳遞有一些看法,現(xiàn)在整理一下,對(duì)自己的學(xué)習(xí)做個(gè)記錄。
首先,需要先清楚java中的變量類型
java中的變量有兩類:primitive主數(shù)據(jù)類型和引用
其中主數(shù)據(jù)類型又分為八種:
boolean char byte short int long float double
然后,需要先清楚java中的變量類型的區(qū)別
那主數(shù)據(jù)類型和引用類型有什么區(qū)別呢?
int num = 10;
String str = "hello";

-
num是int類型,屬于主數(shù)據(jù)類型,該變量的內(nèi)存空間直接存儲(chǔ)了值10。 - 而
str屬于引用類型,該變量?jī)?nèi)存空間存儲(chǔ)的是String對(duì)象"hello"的地址,實(shí)際上也就是引用了這個(gè)對(duì)象。
接著,需要搞清楚String類型存儲(chǔ)在Heap上還是String Pool中
- 直接賦值字符串,會(huì)引用
String Pool中的對(duì)象(如果沒有就創(chuàng)建),這是在編譯期就完成的。
String a = "hello";
String b = "hello";
System.out.println(a == b); //true

-
new String會(huì)在垃圾回收堆上創(chuàng)建對(duì)象并引用(堆上創(chuàng)建時(shí)會(huì)從String Pool中深拷貝),這是在運(yùn)行時(shí)完成的。
String a = new String("hello") ;
String b = new String("hello") ;
System.out.println(a == b); //false

最后,我們以兩個(gè)傳參的例子來講
//示例一
String a = "hello";
String b = foo(a);
System.out.println(a == b); //false
String foo(String str) {
str = str + "world";
return str;
}
解析:用+做字符串連接時(shí)會(huì)返回新的String對(duì)象,而不是在原有的對(duì)象上操作。
foo將實(shí)參a傳遞給形參str,相當(dāng)于執(zhí)行了str=a,此時(shí)str和a都引用了同一個(gè)對(duì)象,但當(dāng)執(zhí)行 str=str+"world"; 后,str引用了+操作符返回的一個(gè)新的String對(duì)象,值為helloworld,b就是str,而a還是引用之前的對(duì)象,值為hello,所以結(jié)果為false。
//示例二
StringBuilder a = new StringBuilder("hello");
StringBuilder b = foo(a);
System.out.println(a == b); //true
StringBuilder foo(StringBuilder builder) {
builder = builder.append("world");
return builder;
}
解析:示例二和示例一的區(qū)別在于StringBuilder類的append方法不會(huì)返回新的String對(duì)象,而是在原有String對(duì)象上操作,所以結(jié)果為true,a與b的值均為helloworld。

總結(jié)
對(duì)于java到底是值傳遞還是引用傳遞,很多人有自己的理解,甚至很多人還在爭(zhēng)辯值傳遞和引用傳遞的定義,我覺得這些字面理解對(duì)于初學(xué)者都是沒有意義的,我們最應(yīng)該關(guān)注的是傳遞本身到底做了什么事情。
- 主數(shù)據(jù)類型不必多說,它是傳遞了一個(gè)值的拷貝,也就是副本,所有的操作與原來的值再無(wú)關(guān)聯(lián)。
- 引用類型的話,我們只需要關(guān)注值在傳遞后有沒有生成新的對(duì)象,如果生成了新的對(duì)象,所有操作與原值無(wú)關(guān),如上示例一。如果沒有生成新的對(duì)象,將會(huì)在原值上操作,傳遞前后的兩個(gè)變量是一條繩上的螞蚱,你變我也變,如上示例二。
學(xué)習(xí)資料:
- java到底是值傳遞還是引用傳遞?--知乎
- Head First Java 對(duì)象引用(54--58), String 不變性(附錄B#9) 。