Java 值傳遞和物件傳遞詳解
阿新 • • 發佈:2019-01-29
1、需要明白的概念:
堆和棧:Java中基本資料型別的值和物件的引用儲存在棧中,具體物件值儲存在堆中。
傳遞原理:
一個方法傳遞的引數如果是基本資料型別,則是對具體值的拷貝;如果是物件資料型別,則是對物件引用地址值的拷貝,而非具體值拷貝。下面分析三種情況:
①一個方法不能改變傳入基本型別的引數值。
示例程式碼:
public class Test2 {
public static void main(String[] args) {
int a = 1;
System.out.println("--->>>before a:" +a);
change(a);
System.out.println("--->>>after a:"+a);
}
private static void change(int b){
b = 2;
System.out.println("--->>>current b:"+b);
}
}
列印:
--->>>before a:1
--->>>current b:2
--->>>after a:1
圖解:
說明:
b=2單獨開了一片空間,和a沒有任何關係,所以改變b是不會對a的值有任何影響的。
②一個方法不能改變傳入物件型別的引數的引用地址。
示例程式碼:
public class Test3 {
public static void main(String[] args) {
Person pa = new Person("張三");
System.out.println("--->>>before pa:"+pa.getName());
change(pa);
System.out.println("--->>>after pa:" +pa.getName());
}
private static void change(Person pb){
Person pc = new Person("李四");
pb = pc;
System.out.println("--->>>current pc:"+pc.getName());
System.out.println("--->>>current pb:"+pb.getName());
}
public static class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
列印:
--->>>before pa:張三
--->>>current pc:李四
--->>>current pb:李四
--->>>after pa:張三
圖解:
說明:
當開始呼叫change(pa)的時候,實際上是將pa的地址拷貝了一份然後給了pb,所以pa和pb都指向張三;
pc是從新new的,會重新開闢棧區和堆區的空間;
然後經過pb = pc的賦值操作後,實際上是讓他們同時指向堆區的李四。
③一個方法能夠改變傳入物件型別的引數某一個屬性。
例項程式碼:
public class Test4 {
public static void main(String[] args) {
Person pa = new Person("張三");
System.out.println("--->>>before pa:"+pa.getName());
change(pa);
System.out.println("--->>>after pa:"+pa.getName());
}
private static void change(Person pb){
pb.setName("李四");
System.out.println("--->>>current pb:"+pb.getName());
}
public static class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
列印:
--->>>before pa:張三
--->>>current pb:李四
--->>>after pa:李四
圖解:
說明:
呼叫change(pa)方法後,實際上是將pa的地址拷貝了一份然後給了pb,所以pa和pb都指向張三;
呼叫pb.setName(“李四”)後,實際上是將張三變成了李四,pa和pb引用地址不變,所以pa和pb都指向了李四。
總結:
①一個方法不能改變傳入基本型別的引數值。
②一個方法不能改變傳入物件型別的引數的引用地址。
③一個方法能夠改變傳入物件型別的引數某一個屬性。