標籤:
當用final作用於類的成員變數時,成員變數(注意是類的成員變數,局部變數只需要保證在使用之前被初始化賦值即可)必須在定義時或者構造器中進行初始化賦值,而且final變數一旦被初始化賦值之後,就不能再被賦值了。
那麼final變數和普通變數到底有何區別呢?下面請看一個例子:
public class Test { public static void main(String[] args) { String a = "hello2"; final String b = "hello"; String d = "hello"; String c = b + 2; String e = d + 2; System.out.println((a == c)); System.out.println((a == e)); }}
truefalse
大家可以先想一下這道題的輸出結果。為什麼第一個比較結果為true,而第二個比較結果為fasle。這裡面就是final變數和普通變數的區別了,當final變數是基礎資料型別 (Elementary Data Type)以及String類型時,如果在編譯期間能知道它的確切值,則編譯器會把它當做編譯期常量使用。也就是說在用到該final變數的地方,相當於直接存取的這個常量,不需要在運行時確定。這種和C語言中的宏替換有點像。因此在上面的一段代碼中,由於變數b被final修飾,因此會被當做編譯器常量,所以在使用到b的地方會直接將變數b 替換為它的 值。而對於變數d的訪問卻需要在運行時通過連結來進行。想必其中的區別大家應該明白了,不過要注意,只有在編譯期間能確切知道final變數值的情況下,編譯器才會進行這樣的最佳化,比如下面的這段代碼就不會進行最佳化:
public class Test { public static void main(String[] args) { String a = "hello2"; final String b = getHello(); String c = b + 2; System.out.println((a == c)); } public static String getHello() { return "hello"; }}
這段代碼的輸出結果為false。
Java基礎-final變數和普通變數的區別