Java學習記錄--參數傳遞分析
標簽(空格分隔): java
今天做項目,發現了一個問題,當String作為參數傳遞的時候,在函數內部改變值對外部的變量值無影響,如下代碼:
public static void main(String[] args) {
String str = "11111";
changeStr(str);
System.out.println(str);//輸出11111
}
public static void changeStr(String str){
str = "22222";
}
一開始不解后來想想就明白了,遂去對java參數傳遞做一個總結,以加深自己的基礎知識.
1.基本類型傳遞
對于:
- 整型: byte short int long
- 浮點型 float double
- 邏輯型 boolean
- 字符型 char
四類八種基本類型來說,傳遞的都是值,因為這些值是直接保存在棧內存中的,所以傳遞的時候直接拷貝過去了.
public static void main(String[] args) {
int num = 0;
change(num);
System.out.println(num);//輸出0
}
public static void change(int numChange){
numChange =5;
}
結構如下圖,也因此最外層的num的值并沒有受到影響.
20161206212704790.jpg
2.對象傳遞
2.1 例一
對象傳遞,本質上也都是值傳遞,只不過傳遞的值是該引用的拷貝.看下面實例和圖解:
public static void main(String[] args) {
Person person = new Person("aaa", 11);
change(person);
System.out.println(person);//輸出 bbb 11
}
public static void change(Person personChange){
personChange.setName("bbb");
}
結構圖如下:
當執行change的時候,會把person變量的指向的地址拷貝一份給personChange,兩者都指向同一個堆內存,即使后面做了set方法修改,但是對兩者的執行毫無影響.
20161206212704790.jpg
2.2例二
例二和之前的不同之處在change里面,對personChange進行了new操作.代碼如下:
public static void main(String[] args) {
Person person = new Person("aaa", 11);
change(person);
System.out.println(person);//輸出 aaa 11
}
public static void change(Person personChange){
personChange = new Person("bbb",12);
}
結構圖如下:
當執行change的時候,會把person變量的指向的地址拷貝一份給personChange,兩者都指向同一個堆內存,接下new操作會在堆中重新創建一個person對象,此時personChange則指向這個對象,而原person的指向沒發生變化,故輸出aaa 11.
20161206212704790.jpg
2.3 例三
例三是綜合例一和例二,前面兩個搞懂的話這個就很容易懂了.
public static void main(String[] args) {
Person person = new Person("aaa", 11);
change(person);
System.out.println(person);//輸出 ccc 11
}
public static void change(Person personChange){
personChange.setName("ccc");
personChange = new Person("bbb",12);
}
結構圖如下:
讀者自己理解下,不懂的話再看看前面的,看看為什么輸出CCC 11
20161206212704790.jpg
2.4特殊的String
終于到最初的問題,為什么String是對象,但是卻不符合上面對象傳遞測試出來的結果?
public static void main(String[] args) {
String str = "11111";
changeStr(str);
System.out.println(str);//輸出11111
}
public static void changeStr(String str){
str = "22222";
}
原因:
因為String對象具有不可變性,所以針對操作str = "22222"
,在String池中不存在的時候,就是相當于str = new String()
,這樣變化下的話,那么就和例一 一模一樣了,具體圖就不畫了,希望對你有幫助.
3.總結
要理解上面的結果,就要認為Java中只有值傳遞:
- 對于基本類型,直接拷貝值傳遞過去
- 對于對象,拷貝當前對象的引用地址,然后把該地址傳遞過去,所以也是值傳遞.