圖解JAVA參數傳遞

今天作項目,發現了一個問題,當String做爲參數傳遞的時候,在函數內部改變值對外部的變量值無影響,以下代碼:java

 public static void main(String[] args) {
        String str = "11111";
        changeStr(str);
        System.out.println(str);//輸出11111
    }
    public static void changeStr(String str){
        str = "22222";
    }

一開始很不解,後來想明白了,遂去對java參數傳遞作一個總結,以加深本身的基礎知識.函數

1.基本類型傳遞

對於:測試

  • 整型: byte short int long
  • 浮點型 float double
  • 邏輯型 boolean
  • 字符型 char

四類八種基本類型來講,傳遞的都是值,由於這些值是直接保存在棧內存中的,因此傳遞的時候直接拷貝過去了.spa

public static void main(String[] args) {
        int num = 0;
        change(num);
        System.out.println(num);//輸出0
    }
    public static void change(int numChange){
        numChange =5;
    }

結構以下圖,也所以最外層的num的值並無受到影響.code

2.對象傳遞

2.1 例一

對象傳遞,本質上也都是值傳遞,只不過傳遞的值是該引用的拷貝.看下面實例和圖解:對象

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");
    } 

結構圖以下:
當執行change的時候,會把person變量的指向的地址拷貝一份給personChange,二者都指向同一個堆內存,即便後面作了set方法修改,可是對二者的執行毫無影響.blog

2.2例二

例二和以前的不一樣之處在change裏面,對personChange進行了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);
    }

結構圖以下:博客

當執行change的時候,會把person變量的指向的地址拷貝一份給personChange,二者都指向同一個堆內存,接下new操做會在堆中從新建立一個person對象,此時personChange則指向這個對象,而原person的指向沒發生變化,故輸出aaa 11.class

2.3 例三

例三是綜合例一和例二,前面兩個搞懂的話這個就很容易懂了.

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);
    }

結構圖以下:

讀者本身理解下,不懂的話再看看前面的,看看爲何輸出CCC 11

2.4特殊的String

終於到最初的問題,爲何String是對象,可是卻不符合上面對象傳遞測試出來的結果?

 public static void main(String[] args) {
        String str = "11111";
        changeStr(str);
        System.out.println(str);//輸出11111
    }
    public static void changeStr(String str){
        str = "22222";
    }

緣由:
由於String對象具備不可變性,因此針對操做str = "22222",在String池中不存在的時候,就是至關於str = new String(),這樣變化下的話,那麼就和例一 如出一轍了,具體圖就不畫了,但願對你有幫助.
ps:若是想改變的話,可使用Holder包裝類包裝String,能夠參考博文:Java基礎系列18:Holder技術的實現原理分析 | zifangsky的我的博客

3.總結

要理解上面的結果,就要認爲Java中只有值傳遞:

  • 對於基本類型,直接拷貝值傳遞過去
  • 對於對象,拷貝當前對象的引用地址,而後把該地址傳遞過去,因此也是值傳遞.
相關文章
相關標籤/搜索