java按值傳遞理解


Java沒有引用傳遞只有按值傳遞,沒有引用傳遞只有按值傳遞,值傳遞。

通過下面代碼解釋:

 1 public class Test {
 2     public static void main(String[] args ){    
 3         int var = 1 ;    
 4         f(var) ;    
 5         System.out.println(var) ;    
 6     }
 7     public static void f(int newVar ){    
 8         newVar = 2 ;    
 9     }
10 }

執行結果: 

1

分析:

當執行 int var = 1 時,jvm在棧中開辟一塊空間存放值---1,同時var變量指向值1所對應的內存空間,也就是var變量也有自己的內存空間,不過它的空間里存放的是值1所對應的內存地址。

 

當執行到第七行,要將var的值傳遞進方法f中時,jvm執行的操作是創建一個新的變量newVar,並將var里存放的值(也就是值1的內存地址)復制一份給newVar。

當執行到第八行時,jvm重新開辟值--2所對應的存儲空間來存儲值2,並修改了newVar里存放的地址值。

方法返回,執行到第五行,輸出var所指向的值,當然是值1,因為var中的地址值根本沒有變化。

上面示例用的是int,一個基本數據類型,對於引用數據類型同樣適用,因為java中沒有引用傳遞,只有值傳遞。例如自定義的類UserClass:

 1 class MyClass {
 2     int var1 ;
 3 }
 4 public class Test {
 5     public static void main(String[] args ){    
 6         MyClass myClass = new MyClass() ;
 7         myClass.var1 = 1 ;
 8         f(myClass) ;    
 9         System.out.println(myClass.var1) ;    
10     }
11     public static void f(MyClass newMyClass ){
12         myClass.var1 = 100 ;
13     }
14 }

執行結果:

100

分析:

第六行:在棧中創建一個變量指向在堆中創建的對象。關於堆中對象屬性的存儲可以理解為每創建一個對象就會在堆中分配一塊內存空間給改對象,這塊內存空間中記錄了該對象屬於哪個類,剩下就是存儲該對象的屬性值。

 

第七行修改對象屬性值:

 

下面就是關鍵的第八行值的傳遞了,jvm會在棧中在開辟一塊空間newMyClass,然后把myClass里的內容拷貝進newMyClass,這樣在方法f中對newMyClass的修改就是對MyClass所對應內容的修改,因為newMyClass也是指向與myClass同樣的一塊內存空間。

第十二行中對newMyClass屬性的修改同樣會影響myClass所指的內容,因為他們倆指的是同一塊內存空間。

最后方法返回myClass所指內容同樣被修改。

下面說一個比較特殊的類----String,這是java中的一個特殊的引用類型,使用String傳遞時會發現在方法中修改不會影響到方法外的值,例如下面這段代碼:

 1 public class Test {
 2     public static void main(String[] args ){    
 3         String var = "Hello" ;
 4         f(var) ;
 5         System.out.println(var) ;
 6     }
 7     public static void f(String newVar ){
 8         newVar = "World" ;
 9     }
10 }

運行結果:

Hello

在分析這段代碼之前需要知道String的底層是怎樣實現的,其實String是通過char數組來完成其功能,簡單的說String就是對char[]的一個封裝。還要明白直接“字符串內容”和使用new String(“字符串內容”)效果是一樣的,只不過jvm對這兩種創建的字符串存儲的地方不同而已。對上面這段代碼的分析當然還要使用對引用數據傳值方法分析。

第三行jvm在靜態存儲區存放創建的“Hello”字符串,並在棧中開辟var指向Hello的地址(var中存儲的值是Hello字符串的地址)。當將var作為參數傳遞時,jvm會在棧中新創建一個變量newVar,這時newVar是指向"Hello"內存區的,但是在第八行 newVar = “World”卻把newVar中存儲的“Hello”地址改為一個新創建的“World”String對象的地址,注意,var內存儲的地址仍然是“Hello”,所以在方法返回時輸出的仍然是Hello。

終於寫完了~~~ 發現自己想和寫完全是兩碼事‘(*>﹏<*)′,其中一定有錯誤,在內存分配地方沒有說清楚,因為我也不太清楚,還有就是關於對象中屬性的內存分配,這個我真不知道,哪位知道別忘告訴我~~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM