2014-12-04 106 views
0

假設我有兩個類如下Java:嚴格類型檢查失敗?

class A 
{ 
    private Double value; 
    ... 
    //getters and setters 
} 

class B 
{ 
    private Double value; 
    ... 
    //getters and setters 
} 

更新

public static void main(String[] args) 
{ 
    A a = new A(); 
    B b = new B(); 
    a.setValue(b.getValue() != null ? b.getValue() : 0); //works! 
    a.setValue(0); //doesn't work 
} 

和聲明

  1. a.setValue(b.getValue != null ? b.getValue : 0);工作正常,但

  2. a.setValue(0)不起作用我需要將該值設置爲0D才能使其正常工作。

爲什麼我不用寫D隨着在第一種情況下0

+0

請展示一個簡短但完整的程序來展示問題。我們不能輕易說出這裏發生了什麼。 – 2014-12-04 07:07:07

+0

那是因爲0被編譯器視爲整數類型,整數不能直接賦值爲double,所以你需要指定'D'來告訴編譯器它是一個double值。 – 2014-12-04 07:09:09

+0

@JonSkeet我已經更新了一些代碼,希望對你有所幫助 – eatSleepCode 2014-12-04 07:10:02

回答

5

懷疑的問題是,你有

setValue(Double value) 

現在你的條件表達式的類型(b.getValue() != null ? b.getValue() : 0)爲double,以下JLS section 15.25.2規則:

如果一個的操作數是T,其中TByte,ShortCharacter,另一個操作數是常數e int類型的表達式的值可用U這個類型表示,它是應用拆箱轉換爲T的結果,那麼條件表達式的類型爲U

...這很好,因爲你然後用double說法叫setValue,以及可裝箱爲Double

然而,當你嘗試調用setDouble(0)你想叫setValueint說法,那不能裝箱到Double ...因此錯誤,並因此成功傳遞時0D代替。

注意,你並不需要方法調用等,以證明這一點 - 這裏有一個簡單的例子:

Double x = 0d;   
Double y = true ? x : 0; // Fine 
Double z = 0; // Error 
1

只是作爲補充,喬恩的答案,我建議你使用原始的包裝類型對於實際需要的字段,變量和參數類型。

使用相應的基元類型通常效率更高。並且有更少的「邊緣案例」讓你動起來/讓你的代碼變得更加脆弱。

(其中一個邊緣情況是==的語義是......非直觀的,另一個是你可以在原始類型不會/不能給你的情況下得到神祕的NullPointerException。)