常數表示式
常量表示式是一個表示式,它產生一個基本型別或一個 String,並且其值可以在編譯時計算為文字。表示式必須在不丟擲異常的情況下進行求值,並且必須僅由以下內容組成:
-
原始和字串文字。
-
型別轉換為基本型別或
String。 -
以下一元運算子:
+,-,~和!。 -
以下二元運算子:
*,/,%,+,-,<<,>>,>>>,<,<=,>,>=,==,!=,&,^,|,&&和||。 -
三元條件運算元
?:。 -
帶括號的常量表示式。
-
引用常量變數的簡單名稱。 (常量變數是宣告為
final的變數,其中初始化表示式本身是一個常量表示式。) -
<TypeName> . <Identifier>形式的合格名稱,用於引用常量變數。
請注意,上面的列表不包括 ++和 --,賦值運算子,class 和 instanceof,方法呼叫以及對常規變數或欄位的引用。
String 型別的常量表示式導致 interned``String,並且使用 FP-strict 語義評估常量表示式中的浮點運算。
用於常量表示式
可以在任何可以使用普通表示式的地方使用常量表示式(幾乎)。但是,它們在以下情況下具有特殊意義。
switch 語句中的 case 標籤需要常量表示式。例如:
switch (someValue) {
case 1 + 1: // OK
case Math.min(2, 3): // Error - not a constant expression
doSomething();
}
當賦值右側的表示式是常量表示式時,賦值可以執行原始縮小轉換。只要常量表示式的值在左側型別的範圍內,就允許這樣做。 (參見 JLS 5.1.3 和 5.2 )例如:
byte b1 = 1 + 1; // OK - primitive narrowing conversion.
byte b2 = 127 + 1; // Error - out of range
byte b3 = b1 + 1; // Error - not a constant expession
byte b4 = (byte) (b1 + 1); // OK
當常量表示式用作 do,while 或 for 中的條件時,它會影響可讀性分析。例如:
while (false) {
doSomething(); // Error - statenent not reachable
}
boolean flag = false;
while (flag) {
doSomething(); // OK
}
(請注意,這不適用於 if 語句 .Java 編譯器允許 if 語句的 then 或 else 塊無法訪問。這是 C 和 C++中條件編譯的 Java 模擬。)
最後,一個類或具有常量表示式初始化器的介面中的 static final 欄位被急切初始化。因此,即使在類初始化依賴圖中存在迴圈,也可以保證在初始化狀態下觀察這些常量。
有關更多資訊,請參閱 JLS 15.28。常數表示式 。