1. 程式人生 > >Java之把String物件作為方法的引數

Java之把String物件作為方法的引數

看一段程式碼:

public class StringTest {

	public void StringPassTest(String s, String[] ss) {
		s = "abc";
		ss[0] = "abc";
	}

	public static void main(String[] args) {
		String s1 = "good";
		String[] ss = { "edf" };
		StringTest stringTest = new StringTest();

		stringTest.StringPassTest(s1, ss);
		System.out.println(s1 + ss[0]);
	}
}

輸出結果:


從輸出結果與可以看出:s1的值竟然沒改!ss的值改了。

對於函式StringPassTest來說,String 型別的傳遞是引用傳遞,也即是地址傳遞。這個是毋庸置疑的。因為在java裡,String是物件型別,作為引數肯定是引用傳遞。

ss引數完全符合引用傳遞的特點,很好理解。

下面來看一下String的建構函式實現,版本為jdk1.8:

    /**
     * Initializes a newly created {@code String} object so that it represents
     * the same sequence of characters as the argument; in other words, the
     * newly created string is a copy of the argument string. Unless an
     * explicit copy of {@code original} is needed, use of this constructor is
     * unnecessary since Strings are immutable.
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

this.value為:
 /** The value is used for character storage. */
    private final char value[];

所以從以上程式碼可以看出:String內部是用char[]來儲存字串的,String相當於char[]的包裝類,在Java中,包裝類的特質就是值操作時體現對應的基本型別的特質,這就是為什麼會有傳值的效果!

這個示例也給我們一個啟示:當寫一個函式傳遞陣列的時候,不要直接對內部成員進行賦值,否則結果就是不可控的。

比如下面這個函式,如果m_myArray被改了,那麼傳遞的這個陣列也會改變,因為是引用傳遞!

	public void setArray(String[] newArray)  
    {  
        this.m_myArray = newArray;  
    } 


最好使用下面的方法:

public void setArrayNew(String[] newArray)  
    {  
        if(newArray == null)  
        {  
            this.m_myArray = new String[0];  
        }  
        else  
        {  
            this.m_myArray = new String[newArray.length];  
            System.arraycopy(newArray, 0, this.m_myArray, 0, newArray.length);  
        }  
    }