java面试题解惑_JAVA面试题解惑系列(五)——传了值还是传了引用?
作者:臧圩人(zangweiren)
網(wǎng)址:http://zangweiren.javaeye.com
>>>轉(zhuǎn)載請注明出處! < < <
JAVA中的傳遞都是值傳遞嗎?有沒有引用傳遞呢?
在回答這兩個問題前,讓我們首先來看一段代碼:
Java代碼
public final class ParamTest {
// 初始值為0
protected int num = 0;
// 為方法參數(shù)重新賦值
public void change(int i) {
i = 5;
}
// 為方法參數(shù)重新賦值
public void change(ParamTest t) {
ParamTest tmp = new ParamTest();
tmp.num = 9;
t = tmp;
}
// 改變方法參數(shù)的值
public void add(int i) {
i += 10;
}
// 改變方法參數(shù)屬性的值
public void add(ParamTest pt) {
pt.num += 20;
}
public static void main(String[] args) {
ParamTest t = new ParamTest();
// 為基本類型參數(shù)重新賦值
t.change(t.num);
System.out.println(t.num);
// 為引用型參數(shù)重新賦值
t.change(t);
System.out.println(t.num);
// 改變基本類型參數(shù)的值
t.add(t.num);
System.out.println(t.num);
// 改變引用類型參數(shù)所指向?qū)ο蟮膶傩灾?/p>
t.add(t);
System.out.println(t.num);
}
}
這段代碼的運行結(jié)果如下:
0
0
0
20
從上面這個直觀的結(jié)果中我們很容易得出如下結(jié)論:
對于基本類型,在方法體內(nèi)對方法參數(shù)進行重新賦值,并不會改變原有變量的值。
對于引用類型,在方法體內(nèi)對方法參數(shù)進行重新賦予引用,并不會改變原有變量所持有的引用。
方法體內(nèi)對參數(shù)進行運算,不影響原有變量的值。
方法體內(nèi)對參數(shù)所指向?qū)ο蟮膶傩赃M行運算,將改變原有變量所指向?qū)ο蟮膶傩灾怠?/p>
上面總結(jié)出來的不過是我們所看到的表面現(xiàn)象。那么,為什么會出現(xiàn)這樣的現(xiàn)象呢?這就要說到值傳遞和引用傳遞的概念了。這個問題向來是頗有爭議的。
大家都知道,在JAVA中變量有以下兩種:
基本類型變量,包括char、byte、short、int、long、float、double、boolean。
引用類型變量,包括類、接口、數(shù)組(基本類型數(shù)組和對象數(shù)組)。
當(dāng)基本類型的變量被當(dāng)作參數(shù)傳遞給方法時,JAVA虛擬機所做的工作是把這個值拷貝了一份,然后把拷貝后的值傳遞到了方法的內(nèi)部。因此在上面的例子中,在調(diào)用
Java代碼
// 為方法參數(shù)重新賦值
public void change(int i) {
i = 5;
}
方法的情況下,變量i和ParamTest型對象t的屬性num具有相同的值,卻是兩個不同變量。變量i是由JAVA虛擬機創(chuàng)建的作用域在change(int i)方法內(nèi)的局部變量,在這個方法執(zhí)行完畢后,它的生命周期就結(jié)束了。在JAVA虛擬機中,它們是以類似如下的方式存儲的:
[img]http://zangweiren.javaeye.com/upload/picture/pic/17754/bf858157-cd1b-3e9e-9fd1-374906bfd90f.jpg[/img]
很明顯,在基本類型被作為參數(shù)傳遞給方式時,是值傳遞,在整個過程中根本沒有牽扯到引用這個概念。這也是大家所公認(rèn)的。對于布爾型變量當(dāng)然也是如此,請看下面的例子:
Java代碼
public final class BooleanTest {
// 布爾型值
boolean bool = true;
// 為布爾型參數(shù)重新賦值
public void change(boolean b) {
b = false;
}
// 對布爾型參數(shù)進行運算
public void calculate(boolean b) {
b &= false;
// 為了方便對比,將運算結(jié)果輸出
System.out.println("運算后的值:" + b);
}
public static void main(String[] args) {
BooleanTest t = new BooleanTest();
// 為布爾型參數(shù)重新賦值
t.change(t.bool);
System.out.println(t.bool);
// 改變布爾型參數(shù)的值
t.calculate(t.bool);
System.out.println(t.bool);
}
}
輸出結(jié)果如下:
true
運算后的值:false
true
那么當(dāng)引用型變量被當(dāng)作參數(shù)傳遞給方法時JAVA虛擬機又是怎樣處理的呢?同樣,它會拷貝一份這個變量所持有的引用,然后把它傳遞給JAVA虛擬機為方法創(chuàng)建的局部變量,從而這兩個變量指向了同一個對象。在篇首所舉的示例中,ParamTest類型變量t和局部變量pt在JAVA虛擬機中是以如下的方式存儲的:
[img]http://zangweiren.javaeye.com/upload/picture/pic/17756/3c3c237f-bd06-3e7a-a0d9-a2317754b560.jpg[/img]
有一種說法是當(dāng)一個對象或引用類型變量被當(dāng)作參數(shù)傳遞時,也是值傳遞,這個值就是對象的引用,因此JAVA中只有值傳遞,沒有引用傳遞。這種說法顯然是混淆了值和引用的概念。
值傳遞中的值指的是基本類型的數(shù)值,即使對于布爾型,雖然它的表現(xiàn)形式為true和false,但是在棧中,它仍然是以數(shù)值形式保存的,即0表示true,其它數(shù)值表示false。而引用是我們用來操作對象的工具,它包含了對象在堆中保存地址的信息。即使在被作為參數(shù)傳遞給方法時,實際上傳遞的是它的拷貝,但那仍是引用。
最后我們得出如下的結(jié)論:
基本類型和基本類型變量被當(dāng)作參數(shù)傳遞給方法時,是值傳遞。在方法實體中,無法給原變量重新賦值,也無法改變它的值。
對象和引用型變量被當(dāng)作參數(shù)傳遞給方法時,是引用傳遞。在方法實體中,無法給原變量重新賦值,但是可以改變它所指向?qū)ο蟮膶傩浴?/p>
總結(jié)
以上是生活随笔為你收集整理的java面试题解惑_JAVA面试题解惑系列(五)——传了值还是传了引用?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: join orcl的left_oracl
- 下一篇: java后ping不是内部_ping不是