標籤:
一、滿足以下三個條件,一個final變數就不再是一個變數,而是一個直接量。
- 使用final修飾符修飾。
- 在申明的時候就進行初始化
- 初始化的值在編譯器就可以確定。
二、在什麼情況下初始化的值在編譯期是可以確定下來的?
被賦的運算式只是基本的算術運算式或字串連結運算,沒有訪問普通變數,調用方法。
package fianlFieldCase;public class Test { public static void main(String[] args) { final String str1 = "final" + "field"; final String str2 = "java" + 8; //下面的str3的值因為調用了方法,所以值在編譯期不能確定 final String str3 = "java" + String.valueOf(8); final int a = 2 + 3; final double b = 1.5 / 3; System.out.println("java8" == str2); System.out.println("java8" == str3); }}
編譯以後的class檔案如下:
從編譯以後的結果可以看出,除了str3,其他變數的值在編譯期間就可以確定下來的。由於str2是一個直接量,它直接被替換成"java8",str2便指向字串常量池中的"java8",所以當"java8"和str2進行==比較的時候直接返回true。但是str3的值要在運行期才能確定,這樣就不能指向常量池中的”java8“。
常量池是專門用於管理在編譯期被確定並被儲存在已編譯的class檔案中的一些資料。它包括了關於類、方法、介面中的常量,還包括字串常量。
例如執行String a = "java",就會在字串常量區緩衝一個"java";當再執行String b = "java",b就直接指向剛剛緩衝的"java"。所以a==b 返回true。
【JAVA】在編譯期可直接替換的final變數