常數表示式
常量表示式是一個表示式,它產生一個基本型別或一個 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。常數表示式 。