1. 程式人生 > >Java中String型別傳參和char陣列型別傳參的區別(疑問)

Java中String型別傳參和char陣列型別傳參的區別(疑問)

都說java只有一種引數傳遞值傳遞,傳基本型別是值的副本,傳引用型別是引用地址值的副本

為什麼基於副本的兩種修改會有區別呢?

面試題

String str="hello";
char[] c = {'a','b','c'};
void change(String str,char[] c){
str = "world;
c[0] = 'g';
}

呼叫change方法 str輸出hello c[0]='g';
str傳的是它的地址的副本?
c傳的也是它的地址的副本吧?
str不變是因為
對hello的引用是
str---------> "hello" <----------str(全域性變數str的副本)


change方法執行後 方法棧裡的變數釋放 
對hello的引用現在是
str---------> "hello" 
而c
c-----------> {'a','b','c'} <----------c(全域性變數副本)
為什麼c[0]會變呢

寫完沒多久感覺就有思路了 不知道是不是對的 有錯的話希望大家糾正

當在change方法內改變str時,順著str全域性變數的地址是可以在常量池裡找到"hello"字串的,但是hello字串底層其實是一個final修飾的字元陣列,初始化後相當於一個常量,放在常量池中,常量是不可改的,這時候原str地址所指向的字元物件沒有變,還是"hello",而區域性變數地址則指向一個新的字串物件"world"

str------------->"hello"   str(copy)---------->"world"


方法執行結束後 str生命週期結束

記憶體中

str-------------->"hello"

如果String型別底層不是final修飾的字元陣列 而是一個普通的字元陣列 那麼應該結果是 str也變成了

str--------------->"world"

後來又加上了一個person類

class person{
	String name;
	person(String name){
		this.name=name;
	}
	@Override
	public String toString() {
		return "person [name=" + name + "]";
	}
	
}
public class ArrayString {
	@Test
	public void test(){
		String str = "hello";
		char[] c={'a','b','c'};
		person person = new person("大佬");
		this.change(str, c,person);
		System.out.println(person.toString());
	}
	public void change(String str,char[] c,person p) {
		str="world";
		c[0]='g';
		System.out.println(p.toString());
		p.name="大俠";
	}
}

雖然原來寫的時候一直沒有懷疑過為什麼結果會改變了,但是現在

輸出結果為什麼會是 大俠?

由p的地址副本可以找到person物件

有沒有大牛解答一下小弟的疑惑