- import java.util.*;
- class test
- {
- public static void main(String[] args)
- {
- char a[] = {'b', 'a', 'c'};
- String b = "111";
- f(a,b);
- System.out.println(Arrays.toString(a)+" "+b);
- }
- public static void f(char[] a, String b) {
- a[1] = 'c';
- b = "123";
- }
- }
輸出結果爲
- [b, c, c] 111
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修飾,即便獲取到了對象的引用,依然無法更改對象的屬性。
解決方法:通過反射機制來更改。
代碼:
- import java.util.*;
- import java.lang.reflect.*;
- class Test
- {
- public static void main(String[] args) throws Exception
- {
- Integer i = 123;
- Integer j = 456;
- f(i,j);
- System.out.println(i +" "+ j);
- }
- public static void f(Integer i, Integer j)throws Exception {
- int temp = i;
- //拿到字節碼對象
- Class clazz = i.getClass();
- Field value = clazz.getDeclaredField("value");
- value.setAccessible(true);
- value.setInt(i, j);
- value.setInt(j, temp);
- }
- }