2012-12-15 30 views
3

,我有以下的代碼...三大運營商的說法:局部變量可能尚未初始化

import java.util.Random; 

public class ThreeArgumentOperator { 

    private static final Random RANDOM = new Random(); 

    public static void main(String[] args) { 
     String test; 
     System.out.println(test = getValue() == null ? "" : test); 
    } 

    public static String getValue() { 
     if (RANDOM.nextBoolean()) { 
      return ""; 
     } else { 
      return null; 
     } 
    } 

} 

Eclipse編譯器(我用的Juno)報告以下錯誤:

The local variable test may not have been initialized

我的問題是:編譯器不應該在這種情況下報告它寧可不能將boolean轉換爲String?我知道運營商==優先於=,因此編譯器應該抱怨投射,而不是抱怨可能未初始化的值。

當我更改以下行

System.out.println(test = getValue() == null ? "" : test);

System.out.println((test = getValue()) == null ? "" : test);

一切工作正常。

編輯:我也試圖直接使用javac編譯它。它給出了同樣的錯誤。

error: variable test might not have been initialized 
System.out.println(test = getValue() == null ? "" : test); 
+0

它應該和我的情況一樣。 – NPE

+0

@NPE這是否意味着你得到'類型不匹配:不能從布爾轉換爲字符串?如果是這樣,你使用什麼編譯器? – Jagger

+0

我已經在我的Eclipse中測試過了,編譯器給了我你描述的錯誤。順便說一句,我正在使用Sun的JDK 7。 –

回答

5

編譯器向您提供的錯誤是正確的。根據運營商優先級,==將首先評估,然後您的三元運營商? :。這意味着,邏輯的流程如下:

getValue() == null 

爲了繼續,讓我們假設這樣的結果是false。下面的表達式如下:

false ? "" : test 

這樣的結果是test。而我們最終的表達......

test = test 

test從未被初始化,因此錯誤。

+0

這是一個完美的解釋!謝謝。 – Jagger

+0

很高興聽到它有用。 :) – cklab

2

我真的不明白問題所在。第一個表達式是

test = getValue() == null ? "" : test 

這意味着:test

  • 空字符串初始化如果getValue()返回null
  • test否則

值由於測試尚未初始化,但不能初始化test本身,因此錯誤消息。

第二個表達式是

(test = getValue()) == null ? "" : test 

這意味着:

  • 初始化testgetValue()
  • 比較testnull
  • 結果如果test是空的表達式計算得到空字符串
  • 否則計算結果爲test

價值爲什麼不應該把它編譯?

+0

我在哪裏寫第二個不應該編譯?無論如何,謝謝你的回答。 – Jagger

+0

好的,我再次閱讀我的問題,並重新排列了一些句子,這可能會有點含糊。 – Jagger

0

這對我來說非常合適。

第二個編譯版本實際上是兩個單獨的語句。它等效於以下代碼:

test = getValue(); 
System.out.println(test == null ? "" : test); 

第一一個值分配給test

test = getValue(); 

現在test具有值。如果test不爲空,則第二個陳述能夠確定經驗結果值。

第一個非編譯版本是一個語句,因爲test還沒有值,所以分配test(即test)的值是未知的。