JAVA中char和String/值類型和引用類型的區別

[java] view plain copy
  1. import java.util.*;  
  2. class  test  
  3. {  
  4.     public static void main(String[] args)   
  5.     {  
  6.         char a[] = {'b''a''c'};  
  7.         String b = "111";  
  8.         f(a,b);  
  9.         System.out.println(Arrays.toString(a)+"   "+b);  
  10.     }  
  11.   
  12.     public static void f(char[] a, String b) {  
  13.         a[1] = 'c';  
  14.         b = "123";  
  15.     }  
  16. }  

輸出結果爲 

[java] view plain copy
  1. [b, c, c]   111  
爲什麼a改變了值,而b沒有改變?

a是一個數組,按引用傳遞,在另一個方法裏傳遞a時傳遞的是a的內存地址,而不是a的副本,所以形參改變時,實參也會跟着改變。

b是按值傳遞,意味着將b傳遞給函數時,函數接受的是b的一個副本。因此,如果函數修改了該參數,僅改變副本,原始值不遠。


(1)基本數據類型傳值,是將棧中的類型傳一個副本,對形參的修改不會影響實參;
(2)引用類型傳引用,形參和實參指向同一個內存地址(同一個對象),是在堆中。所以對參數的修改會影響到實際的對象;
(3)String, Integer, Double等immutable的類型特殊處理,可以理解爲傳值,最後的操作不會修改實參對象。

八大基本類型 short,int,long,float,double,boolean,char

四大引用類型 數組,類,接口,字符串


引用:

JAVA中沒有引用傳遞都是值傳遞 ,網上講的好多都是錯誤的,希望發帖都以後思考後再發:
在 Java 應用程序中永遠不會傳遞對象,而只傳遞對象引用。因此是按引用傳遞對象。但重要的是要區分參數是如何傳遞的,這纔是該節選的意圖。Java 應用程序按引用傳遞對象這一事實並不意味着 Java 應用程序按引用傳遞參數。參數可以是對象引用,而 Java 應用程序是按值傳遞對象引用的。
Java 應用程序中的變量可以爲以下兩種類型之一:引用類型或基本類型。當作爲參數傳遞給一個方法時,處理這兩種類型的方式是相同的。兩種類型都是按值傳遞的;沒有一種按引用傳遞。
按 值傳遞意味着當將一個參數傳遞給一個函數時,函數接收的是原始值的一個副本。因此,如果函數修改了該參數,僅改變副本,而原始值保持不變。按引用傳遞意味 着當將一個參數傳遞給一個函數時,函數接收的是原始值的內存地址,而不是值的副本。因此,如果函數修改了該參數,調用代碼中的原始值也隨之改變。
當傳遞給函數的參數不是引用時,傳遞的都是該值的一個副本(按值傳遞)。區別在於引用。在 C++ 中當傳遞給函數的參數是引用時,您傳遞的就是這個引用,或者內存地址(按引用傳遞)。在 Java 應用程序中,當對象引用是傳遞給方法的一個參數時,您傳遞的是該引用的一個副本(按值傳遞),而不是引用本身。
Java 應用程序按值傳遞所有參數,這樣就製作所有參數的副本,而不管它們的類型。


基本類型傳遞的是值的副本,
引用類型傳遞的是引用的副本。


2017/09/09 

遇到了一個問題,即便是String、Integer等類的對象,傳進上述函數也無法更改值。

原因:String.,Integer等類的對象裏面封裝了一個屬性value,被private final修飾,即便獲取到了對象的引用,依然無法更改對象的屬性。

解決方法:通過反射機制來更改。

代碼:

[java] view plain copy
  1. import java.util.*;  
  2. import java.lang.reflect.*;  
  3. class Test  
  4. {  
  5.     public static void main(String[] args) throws Exception   
  6.     {  
  7.         Integer i = 123;  
  8.         Integer j = 456;  
  9.         f(i,j);  
  10.         System.out.println(i +"     "+ j);  
  11.     }  
  12.   
  13.     public static void f(Integer i, Integer j)throws Exception {  
  14.         int temp = i;  
  15.         //拿到字節碼對象  
  16.         Class clazz = i.getClass();  
  17.         Field value = clazz.getDeclaredField("value");  
  18.         value.setAccessible(true);  
  19.         value.setInt(i, j);  
  20.         value.setInt(j, temp);  
  21.     }  
  22. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章