值傳遞與引用傳遞

JVM在執行方法main時,會建立java棧(屬於某一個線程,不共享),並將變量 a存儲到局部變量區,在調用方法change時,根據(invoke**)指令,爲change建立一個新的棧幀,並將參數保存在新棧幀的局部變量區,在執行ireturn指令後,將棧頂元素返回到調用方法的棧中,建立的棧幀也被撤銷。PC寄存器指令恢復調用棧的下一條命令地址。繼續執行--java

 

首先要說明的是java中是沒有指針的,java中只存在值傳遞,只存在值傳遞!!!  然而咱們常常看到對於對象(數組,類,接口)的傳遞彷佛有點像引用傳遞,能夠改變對象中某個屬性的值。可是不要被這個假象所矇蔽,實際上這個傳入函數的值是對象引用的拷貝,即傳遞的是引用的地址值,因此仍是按值傳遞。數組

 

 值傳遞函數

    示例:spa

複製代碼
public class Test3 {
    public static void change(int a){
        a=50;
    }
    public static void main(String[] args) {
        int a=10;
        System.out.println(a);
        change(a);
        System.out.println(a);
    }
}
複製代碼

 很顯然輸出的 是10,10。傳遞的是值得一份拷貝,這份拷貝與原來的值沒什麼關係。線程

內存分析:指針

              

  引用傳遞code

      示例:對象

複製代碼
public class Test3 {
    public static void change(int []a){
        a[0]=50;
    }
    public static void main(String[] args) {
        int []a={10,20};
        System.out.println(a[0]);
        change(a);
        System.out.println(a[0]);
    }
}
複製代碼

顯然輸出結果爲10   50。實際傳遞的是引用的地址值。blog

內存分析:接口

            

 

 示例:

複製代碼
class Emp {
    public int age;
}
public class Test {
    public static void change(Emp emp)
    {
        emp.age = 50;
        emp = new Emp();//再建立一個對象
        emp.age=100;
    }
    
    public static void main(String[] args) {
        Emp emp = new Emp();
        emp.age = 100;
        System.out.println(emp.age);
        change(emp);
        System.out.println(emp.age);
        System.out.println(emp.age);
    }
}
複製代碼

輸出爲:100  50  50.

內存分析:

                

對於String類:

複製代碼
public class Test {
    public static void change(String s){
        s="zhangsan";
    }
    
    public static void main(String[] args) {
        String s=new String("lisi");
        System.out.println(s);
        change(s);
        System.out.println(s);
    }
}
複製代碼

輸出爲:lisi   lisi,因爲String類是final修飾的,不可變,它會在內存中在開闢一塊新空間。

相關文章
相關標籤/搜索