[英]Evaluation Respects Parentheses and Precedence - java
根據Java語言規范:
評估尊重括號和優先順序
除了使用數學運算之外:
int i = 3;
int j = 3 * (9 + 3);
System.out.println(j); //results to 36
該規則是否適用於其他任何示例? 我試過用
int i = 0;
int z = 0;
if(i++ < 5 || (++z <0 && 5 > z++) || 6 < ++i){
System.out.println("Routed here");
}
System.out.println("i: " + i);
System.out.println("z: " + z);
但結果是i:1和z:0。 似乎對該示例的評估仍然是從左到右。
隨着||
,Java在評估表達式時使用了短路的概念。 因此,在這:
if(i++ < 5 || (++z <0 && 5 > z++) || 6 < ++i){
因為第一個表達式i++ < 5
返回true,因此表達式的其余部分將不會被評估,即從未被訪問過,因此只會在i
的值中帶來變化,而不會有任何其他東西。
來自Java Docs的引用:
條件運算符&&和|| 運算符對兩個布爾表達式執行條件AND和條件OR運算。 這些運算符表現出“短路”行為,這意味着僅在需要時才評估第二個操作數。 && Conditional-AND || Conditional-OR以下程序ConditionalDemo1測試這些運算符:
class ConditionalDemo1 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}
括號和優先級與運行時計算表達式的順序無關。 也就是說,如果您認為在表達式周圍加括號意味着它將在之前得到評估,或者更早地評估具有更高優先級的運算符,那么您就會誤解這個概念。
運算符優先級回答如下問題:在表達式中
a * b + c
編譯器首先將哪個運算符“綁定”到參數? 如果+
具有更高的優先級,它會在*
之前抓住它附近的參數,可以這么說; 這樣結果就是添加了b
和c
,結果乘以a
。 也就是說,它等同於
a * (b + c)
但在大多數編程語言中(有一些例外,如APL), *
具有更高的優先級。 這意味着參數在綁定到+
之前綁定到*
,這意味着a
和b
相乘,並且結果被添加到c
,即
(a * b) + c
同樣,在表達式中
a + b * c
結果是b
和c
相乘,結果加到a
。
a + (b * c)
您可以在表達式的某些部分周圍加上括號來更改參數的綁定方式; 因此,如果你想添加a
和b
並將總和乘以c
,你可以說
(a + b) * c
但是需要注意的是:所有這些都控制着在編譯時如何解釋表達式。 但是在運行時,參數總是從左到右進行評估。 當程序運行時,所有上述表達式將導致程序評估a
,然后是b
,然后是c
。 如果a
, b
和c
是變量,這無關緊要,但如果它們是方法調用,則可能很重要。 在Java中,當程序運行時,事物總是從左到右進行評估。 (其他語言並非如此;我所知道的大多數語言都讓編譯器選擇順序。)
當涉及到||
和&&
(或其他一些語言中的類似運算符),再次在運行時, 始終首先計算左參數。 可能會或可能不會評估正確的參數。 如果你有一個像some-expression-1 || some-expression-2 && some-expression-3
這樣some-expression-1 || some-expression-2 && some-expression-3
括號和運算符優先級控制表達式的解釋方式 some-expression-1 || some-expression-2 && some-expression-3
,但它們不會在運行時更改評估順序。
只要測試可以被評估為true或false,執行就會在if塊內跳轉。 在你的情況下, i
等於0
,它比5
輕,所以測試評估為true
。
(true OR a OR b)
與a
和b
的值無關,它們不被評估(並且不應用增量)。
它將與(false AND a AND b)
相同,除非它總是跳過塊。
檢查表達式的順序,將它們分成單獨的測試或從測試中獲得增量。 以下代碼等同於您的示例,但具有您期望的輸出:
int i = 0;
int z = 1;
if(i < 5 || (z < 0 && 5 > z+2) || 6 < i+2){
System.out.println("Routed here");
}
i += 2;
z += 2;
System.out.println("i: " + i);
System.out.println("z: " + z);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.