Java基礎07 String以及基礎型別的封裝類是值傳遞的哪一種形式
阿新 • • 發佈:2020-09-10
經過上一篇的部落格(沒看我上一篇部落格的可以點選連結先去了解下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
這個例子也是在上一篇部落格舉的,現在我們來分析下它的執行過程所做的一些操作。
- JVM在堆中開闢一塊記憶體用於儲存 Student 物件,物件包含 name、age兩個屬性。
- JVM在棧中分配一塊記憶體給student,用於儲存指向 Student 物件 的堆地址。
- JVM在複製一份student給student1,分配到棧記憶體中(student與student棧記憶體地址不同,但儲存著相同的堆記憶體地址)。
- 將student1傳入方法體中,改變age的值。
- 方法結束,列印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方法不會改變原來的值。我們帶著疑惑繼續深究下去。
- JVM在堆中開闢一塊記憶體用於儲存 "hello"。
- JVM在棧中分配一塊記憶體給str,用於儲存指向 "hello" 的堆地址。
- JVM在複製一份str給str1,分配到棧記憶體中(str與str1棧記憶體地址不同,但儲存著相同的堆記憶體地址)。
- 將str1傳入方法體中。
- 方法體在堆記憶體中開闢一塊記憶體,用於儲存 "good"。
將str1的值改變,讓其指向儲存 "good" 的堆記憶體地址
。- 方法結束,列印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哈哈~