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修飾的,不可變,它會在內存中在開闢一塊新空間。