首先,Java中并不存在指針,但有類似的現(xiàn)象,叫“引用傳遞”。
一部分人覺得java中存在【引用傳遞】和【值傳遞】,而也有一部分人認為java中只存在【值傳遞】。他們表達的意思是一樣的,卻是從兩個方面來表達。
首先java中的確存在兩種情況。下面來看一個例子;
public class Test {
public static void change(int a){
a=50;
}
public static void main(String[] args) {
int a=10;
System.out.println(a);
change(a);
System.out.println(a);
}
}
輸出:10,10
可見change方法并沒有改變main中的a的值。
這里傳遞到change中的a
是一個拷貝,對原來的值不產(chǎn)生影響。
再看:
public class Test3 {
public static void change(int []a){
a[0]=50;
}
public static void main(String[] args) {
int[] a={10,20};
System.out.println(a[0]);
change(a);
System.out.println(a[0]);
}
}
輸出:10,50;
可見這里的change方法改變了main中的a,
這里傳遞到change中的a
是一個地址的值,指向原來的值。
<br />
深入
我們來看下面的例子:
作者:Intopass
鏈接:https://www.zhihu.com/question/31203609/answer/50992895
來源:知乎
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。
第一個例子:基本類型
void foo(int value) {
value = 100;
}
foo(num); // num 沒有被改變
第二個例子:沒有提供改變自身方法的引用類型
void foo(String text) {
text = "windows";
}
foo(str); // str 也沒有被改變,也因為每一個"xxx"都是一個新的對象
第三個例子:提供了改變自身方法的引用類型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改變了,變成了"iphone4"。
第四個例子:提供了改變自身方法的引用類型,但是不使用,而是使用賦值運算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 沒有被改變,還是 "iphone"。
這里有些人可能對圖四難以理解,為什么foo方法中對傳入的sb做了賦值,但是sb還是沒有改變呢?
那我們再來看看下面的例子和相應(yīng)的內(nèi)存模型:
public static void main(String[] args) {
Demo d1 = new Demo();
fun(d1);
);
}
public void fun(Demo d2){
xxxx;
}
d1、d2內(nèi)存模型
這里我們發(fā)現(xiàn),當(dāng)調(diào)用fun
方法的時候,棧內(nèi)存中出現(xiàn)了d2
值,指向了d1
指向的空間。
這也就解釋了上面第四個例子:當(dāng)調(diào)用foo
方法傳入d1
時,實際上是在棧內(nèi)存中新增了d2
值,同時d2
指向d1
指向的堆內(nèi)存空間。當(dāng)foo
方法內(nèi)部進行新的【賦值】操作時,實際上改變了的是d2
的指向,并不會改變d1的值。
這里我們需要注意的一點是d2的賦值是改變其指向的位置。而不是改變指向位置的值。