簡體   English   中英

Java 表達順序、運算符優先級和結合性之間的差異

[英]Differences between Java order of expression, operator precedence and associativity

我在考試中遇到了這個問題。

考試題:以下代碼片段的結果是什么?

3: var tiger = "Tiger";
4: var lion = "Lion";
5: final var statement = 250 > 338 ? lion : tiger = " is Bigger";
6: System.out.println(statement);

正確答案是

F. 由於第 5 行,代碼將無法編譯

解釋是:

  1. 代碼無法編譯,因為賦值運算符在此表達式中具有最高優先級。
  2. 三元運算符的兩邊必須具有相同的類型。 這個表達式無效,因為第二個賦值運算符的左邊不是變量,所以答案是選項 F。
  3. 請注意,如果問題在表達式周圍添加了顯式括號(Tiger = " is Bigger"),則選項 E 將具有正確的 output。

當我自己運行代碼時,出現編譯錯誤:

test.java:11: error: unexpected type
final var statement = 250 > 338 ? lion : tiger = " is Bigger";
                                ^
  required: variable
  found:    value
1 error
error: compilation failed

在征求第二意見后,閱讀 JLS 第15節,以及這些其他 SO 問題:

Java中評估順序的規則是什么?

如果括號具有更高的優先級,那么為什么首先解決增量運算符?

我提出了幾個理論:

  1. 表達式求值順序、運算符優先級和關聯性是不同的概念。
  2. 根據 JLS 15.7.3,表達式評估尊重括號和運算符優先級。
  3. 所有表達式評估都是從左到右進行的。
  4. 運算符優先級決定了表達式的分組。
  5. 關聯性僅適用於同一運算符,並確定使用同一運算符的表達式的執行順序。
  6. Java 在編譯時檢查有效表達式,從左到右,尊重括號和運算符優先級。
  7. 對於帶有運算符的表達式,它會根據運算符以不同的方式對操作數執行此檢查。

有了新知識,我現在將嘗試解釋為什么第 5 行無法編譯:

  1. Java 使用表達式評估順序從左到右開始檢查有效表達式。
  2. Java 找到第一個賦值運算符(最左邊)。
  3. 由於賦值運算符“=”具有從右到左的關聯性,因此 Java 檢查右側是否還有其他賦值運算符,並開始計算更右的賦值運算符。
  4. 它找到一個“=”,然后檢查右側的任何其他“=”。
  5. 我沒有找到其他“=”,所以它開始評估這個最右邊“=”的操作數。
  6. 根據 15.26,Java 檢查前一個“=”和這個“=”之間的所有內容是否只是一個變量。
  7. 它找到表達式250 > 338? lion: tiger 250 > 338? lion: tiger ,這是一個有效的表達式,但這個表達式的計算結果是一個值。
  8. Java 只允許賦值運算符左側的變量,所以編譯失敗。

現在我會嘗試應用同樣的理論來解釋這段代碼的正確場景: final var statement = 250 > 338? lion: (tiger = " is Bigger"); final var statement = 250 > 338? lion: (tiger = " is Bigger");

  1. Java 使用表達式評估順序從左到右開始檢查有效表達式。
  2. Java 在同一個“作用域”中沒有找到任何其他賦值運算符“=”。
  3. 根據 15.26,Java 檢查此“=”的左操作數是否為變量。 通過。
  4. 然后它評估右操作數是否是返回可分配給左操作數的值的有效表達式。

考試提供的解釋是否落空了,還是我仍然不明白這段代碼是如何編譯的?

  1. 他們說賦值運算符“=”在這個表達式中具有最高優先級。 根據此運算符優先級表http://www.cs.bilkent.edu.tr/~guvenir/courses/CS101/op_precedence.html ,賦值運算符的優先級最低。
  2. 他們將運算符優先級與評估表達式的順序互換使用,而不是將這兩個概念分開?

你是對的,他們說錯了,賦值運算符的優先級最低

你是不正確的,他們從來沒有在任何地方提到“評估順序”(無論如何你已經展示過)。 顯示的代碼在評估順序很重要的地方沒有做任何事情。 作業與評估順序無關。



  1. 代碼無法編譯,因為賦值運算符在此表達式中具有最高優先級。

運算符優先級顯示:

9   >   relational
2   ?:  ternary
1   =   assignment

這意味着要使用括號顯式顯示優先級,語句變為:

statement = ((250 > 338) ? lion : tiger) = " is Bigger";

  1. 三元運算符的兩邊必須具有相同的類型。 這個表達式無效,因為第二個賦值運算符的左邊不是變量,所以答案是選項 F。

三元運算符是((250 > 338)? lion: tiger) ,“雙方”指的是兩個賦值運算符。

正如它所說,“這個表達式無效,因為第二個賦值運算符的左側不是變量”。


  1. 請注意,如果問題在表達式周圍添加了顯式括號(Tiger = " is Bigger"),則選項 E 將具有正確的 output。

你自己已經確認過了。

要使用括號顯式顯示優先級,語句變為:

statement = ( (250 > 338) ? lion : (tiger = " is Bigger") );

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM