图解JAVA参数传递
今天做項(xiàng)目,發(fā)現(xiàn)了一個(gè)問題,當(dāng)String作為參數(shù)傳遞的時(shí)候,在函數(shù)內(nèi)部改變值對(duì)外部的變量值無影響,如下代碼:
public static void main(String[] args) {String str = "11111";changeStr(str);System.out.println(str);//輸出11111 }public static void changeStr(String str){str = "22222";}一開始很不解,后來想明白了,遂去對(duì)java參數(shù)傳遞做一個(gè)總結(jié),以加深自己的基礎(chǔ)知識(shí).
1.基本類型傳遞
對(duì)于:
- 整型: byte short int long
- 浮點(diǎn)型 float double
- 邏輯型 boolean
- 字符型 char
四類八種基本類型來說,傳遞的都是值,因?yàn)檫@些值是直接保存在棧內(nèi)存中的,所以傳遞的時(shí)候直接拷貝過去了.
public static void main(String[] args) {int num = 0;change(num);System.out.println(num);//輸出0 }public static void change(int numChange){numChange =5;}結(jié)構(gòu)如下圖,也因此最外層的num的值并沒有受到影響.
2.對(duì)象傳遞
2.1 例一
對(duì)象傳遞,本質(zhì)上也都是值傳遞,只不過傳遞的值是該引用的拷貝.看下面實(shí)例和圖解:
public static void main(String[] args) {Person person = new Person("aaa", 11);change(person);System.out.println(person);//輸出 bbb 11 }public static void change(Person personChange){personChange.setName("bbb");}?結(jié)構(gòu)圖如下:
當(dāng)執(zhí)行change的時(shí)候,會(huì)把person變量的指向的地址拷貝一份給personChange,兩者都指向同一個(gè)堆內(nèi)存,即使后面做了set方法修改,但是對(duì)兩者的執(zhí)行毫無影響.
2.2例二
例二和之前的不同之處在change里面,對(duì)personChange進(jìn)行了new操作.代碼如下:
public static void main(String[] args) {Person person = new Person("aaa", 11);change(person);System.out.println(person);//輸出 aaa 11 }public static void change(Person personChange){personChange = new Person("bbb",12);}結(jié)構(gòu)圖如下:
當(dāng)執(zhí)行change的時(shí)候,會(huì)把person變量的指向的地址拷貝一份給personChange,兩者都指向同一個(gè)堆內(nèi)存,接下new操作會(huì)在堆中重新創(chuàng)建一個(gè)person對(duì)象,此時(shí)personChange則指向這個(gè)對(duì)象,而原person的指向沒發(fā)生變化,故輸出aaa 11.
2.3 例三
例三是綜合例一和例二,前面兩個(gè)搞懂的話這個(gè)就很容易懂了.
public static void main(String[] args) {Person person = new Person("aaa", 11);change(person);System.out.println(person);//輸出 ccc 11 }public static void change(Person personChange){personChange.setName("ccc");personChange = new Person("bbb",12);}結(jié)構(gòu)圖如下:
讀者自己理解下,不懂的話再看看前面的,看看為什么輸出CCC 11
2.4特殊的String
終于到最初的問題,為什么String是對(duì)象,但是卻不符合上面對(duì)象傳遞測(cè)試出來的結(jié)果?
public static void main(String[] args) {String str = "11111";changeStr(str);System.out.println(str);//輸出11111 }public static void changeStr(String str){str = "22222";}原因:
因?yàn)镾tring對(duì)象具有不可變性,所以針對(duì)操作str = "22222",在String池中不存在的時(shí)候,就是相當(dāng)于str = new String(),這樣變化下的話,那么就和例一 一模一樣了,具體圖就不畫了,希望對(duì)你有幫助.
ps:如果想改變的話,可以使用Holder包裝類包裝String,可以參考博文:Java基礎(chǔ)系列18:Holder技術(shù)的實(shí)現(xiàn)原理分析 | zifangsky的個(gè)人博客
3.總結(jié)
要理解上面的結(jié)果,就要認(rèn)為Java中只有值傳遞:
- 對(duì)于基本類型,直接拷貝值傳遞過去
- 對(duì)于對(duì)象,拷貝當(dāng)前對(duì)象的引用地址,然后把該地址傳遞過去,所以也是值傳遞.
轉(zhuǎn)載于:https://www.cnblogs.com/crazyacking/p/6641543.html
總結(jié)
以上是生活随笔為你收集整理的图解JAVA参数传递的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OSChina 周四乱弹 ——巴叔是雾霾
- 下一篇: struts过滤器和拦截器的区别