1. 程式人生 > 實用技巧 >Java基礎07 String以及基礎型別的封裝類是值傳遞的哪一種形式

Java基礎07 String以及基礎型別的封裝類是值傳遞的哪一種形式

  經過上一篇的部落格(沒看我上一篇部落格的可以點選連結先去了解下Java是值傳遞還是引用傳遞),我們瞭解到Java中只有值傳遞,沒有引用傳遞;我們也知道基礎型別的資料傳遞是普通的值傳遞,引用型別(object物件)的資料一般是特殊的值傳遞(求值策略為共享物件傳遞),還有一種引用型別(String 和基礎資料的封裝類)是普通的值傳遞還是特殊的值傳遞呢?我們來一起探究下。

  來探究之前,我們先來看看引用型別為物件的資料傳遞情況:

public class Transmit {

    public static void main(String[] args) {
    	Student student = new Student("小明", 23);
        change(student);
        System.out.println("學生的年齡:" + student.getAge());
    }
    
    private static void change(Student student1){
        student1.setAge(80);
    }

	@Data
    @AllArgsConstructor
    static class Student{
        private String name;
        private int age;
    }
}

列印輸出結果:

學生的年齡:80

這個例子也是在上一篇部落格舉的,現在我們來分析下它的執行過程所做的一些操作。

  1. JVM在堆中開闢一塊記憶體用於儲存 Student 物件,物件包含 name、age兩個屬性。
  2. JVM在棧中分配一塊記憶體給student,用於儲存指向 Student 物件 的堆地址。
  3. JVM在複製一份student給student1,分配到棧記憶體中(student與student棧記憶體地址不同,但儲存著相同的堆記憶體地址)。
  4. 將student1傳入方法體中,改變age的值。
  5. 方法結束,列印student物件的age值,由於在方法中值改變了物件裡面的屬性值,沒有改變student1的指向堆記憶體的地址,所以直接影響到student的資料。

  我們再來看看String以及基礎類的封裝類的情況

public class Transmit {

    public static void main(String[] args) {
    	String str = "hello";
        changeStringValue(str);
        System.out.println("字串的值:" + str);
    }

	private static void changeStringValue(String str1){
        str1 = "good";
    }
}

列印輸出結果:

字串的值:hello

  看到這個結果會不會感到驚訝,String 明明是引用型別,為什麼經過changeStringValue方法不會改變原來的值。我們帶著疑惑繼續深究下去。

  1. JVM在堆中開闢一塊記憶體用於儲存 "hello"。
  2. JVM在棧中分配一塊記憶體給str,用於儲存指向 "hello" 的堆地址。
  3. JVM在複製一份str給str1,分配到棧記憶體中(str與str1棧記憶體地址不同,但儲存著相同的堆記憶體地址)。
  4. 將str1傳入方法體中。
  5. 方法體在堆記憶體中開闢一塊記憶體,用於儲存 "good"。
  6. 將str1的值改變,讓其指向儲存 "good" 的堆記憶體地址
  7. 方法結束,列印str的值,這是由於str與str1指向堆記憶體不同,所以輸出的還是 "hello"。

  基本資料型別的封裝類與 String 一樣,我們只來看下例子的演示效果

public class Transmit {

    public static void main(String[] args) {
    	Integer num = 1;
        changeIntegerValue(num);
        System.out.println("Integer的值:" + num);
    }

	private static void changeIntegerValue(Integer num){
        num = 10;
    }
}

列印輸出結果:

Integer的值:1

  看到這裡,我相信大部分人應該能理解到其中緣由,至於還沒有理解到的,可以多思考思考下,對於JVM方面不太瞭解的看客,可以先去了解下JVM的相關知識,我在後期也會寫JVM系列知識部落格,之後再加進來,JVM知識點有點多,我也不在這敘述了。

  歡迎大家來關注我,讓我們一起成長O(∩_∩)O哈哈~