1. 程式人生 > >Java 值傳遞和物件傳遞詳解

Java 值傳遞和物件傳遞詳解

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都指向了李四。

總結:
①一個方法不能改變傳入基本型別的引數值。

②一個方法不能改變傳入物件型別的引數的引用地址。

③一個方法能夠改變傳入物件型別的引數某一個屬性。