1. 程式人生 > >【編碼技巧】Java-為什麼要給方法引數或一些物件的引用加final?

【編碼技巧】Java-為什麼要給方法引數或一些物件的引用加final?

閱讀原始碼時常常會看到一些例如被這樣修飾的方法引數

public void print(final Object obj){
    System.out.println(obj);
}

你可能會疑問這個final有什麼用,那麼請看下面程式碼

食用final前

Object o = "Hello";
foo(o)
System.out.println(o);//列印結果依舊是"Hello"

void foo(Object o) { o = "Goodbye"; } //此時已經進入棧區!o變數的修改只在此方法內有效

食用final後

Object o = "Hello";
foo(o);
System.out.println(o);//列印結果是"Hello"

void foo(final Object o) { 
    o = "Goodbye"; //oh shit,編譯報錯
} 

在一些不會出現被修改情況的變數前加final,這樣就可以有效防止我們在通宵加班的日子裡寫出各種奇異的bug了。

但這時候你可能會問,既然加final是個好習慣,為什麼Java不給方法引數直接強制加上final呢???

因為有時你會遇到如下圖這種操作

void print(String msg, int count) {
    msg = msg != null ? msg : "DefaultValue";
    while(--count >= 0) {
        System.out.println(msg);
    }
}

如果不直接修改方法引數我們就要宣告更多變數去實現這種操作,很顯然這是很多此一舉的事

 

要知道在Java中不存在C#的ref out這種類似指標的操作

那麼問題來了,如果我需要讓這個方法來修改我傳入的引數再返回給我,又不想用return的方式,那該怎麼辦?

public static void main(String[] args) {
	String[] arg = new String[2];
	set(arg);
	System.out.println(arg[0]);//輸出結果是"233"
}

public static void set(String[] args){
	args[0] = "233";
}

上圖通過陣列的特性實現了你想要的操作,當然這在Java中是一種不優雅的寫法。