首先迁筛,Java中并不存在指針众辨,但有類似的現(xiàn)象端三,叫“引用傳遞”。
一部分人覺得java中存在【引用傳遞】和【值傳遞】鹃彻,而也有一部分人認(rèn)為java中只存在【值傳遞】郊闯。他們表達(dá)的意思是一樣的,卻是從兩個(gè)方面來表達(dá)蛛株。
首先java中的確存在兩種情況团赁。下面來看一個(gè)例子;
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
是一個(gè)拷貝,對(duì)原來的值不產(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
是一個(gè)地址的值析蝴,指向原來的值。
<br />
深入
我們來看下面的例子:
作者:Intopass
鏈接:https://www.zhihu.com/question/31203609/answer/50992895
來源:知乎
著作權(quán)歸作者所有绿淋。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán)闷畸,非商業(yè)轉(zhuǎn)載請注明出處。
第一個(gè)例子:基本類型
void foo(int value) {
value = 100;
}
foo(num); // num 沒有被改變
第二個(gè)例子:沒有提供改變自身方法的引用類型
void foo(String text) {
text = "windows";
}
foo(str); // str 也沒有被改變吞滞,也因?yàn)槊恳粋€(gè)"xxx"都是一個(gè)新的對(duì)象
第三個(gè)例子:提供了改變自身方法的引用類型
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder.append("4");
}
foo(sb); // sb 被改變了佑菩,變成了"iphone4"。
第四個(gè)例子:提供了改變自身方法的引用類型裁赠,但是不使用倘待,而是使用賦值運(yùn)算符。
StringBuilder sb = new StringBuilder("iphone");
void foo(StringBuilder builder) {
builder = new StringBuilder("ipad");
}
foo(sb); // sb 沒有被改變组贺,還是 "iphone"凸舵。
這里有些人可能對(duì)圖四難以理解,為什么foo方法中對(duì)傳入的sb做了賦值失尖,但是sb還是沒有改變呢啊奄?
那我們再來看看下面的例子和相應(yīng)的內(nèi)存模型:
public static void main(String[] args) {
Demo d1 = new Demo();
fun(d1);
);
}
public void fun(Demo d2){
xxxx;
}
這里我們發(fā)現(xiàn)掀潮,當(dāng)調(diào)用fun
方法的時(shí)候菇夸,棧內(nèi)存中出現(xiàn)了d2
值,指向了d1
指向的空間仪吧。
這也就解釋了上面第四個(gè)例子:當(dāng)調(diào)用foo
方法傳入d1
時(shí)庄新,實(shí)際上是在棧內(nèi)存中新增了d2
值,同時(shí)d2
指向d1
指向的堆內(nèi)存空間薯鼠。當(dāng)foo
方法內(nèi)部進(jìn)行新的【賦值】操作時(shí)择诈,實(shí)際上改變了的是d2
的指向,并不會(huì)改變d1的值出皇。
這里我們需要注意的一點(diǎn)是d2的賦值是改變其指向的位置羞芍。而不是改變指向位置的值。