2014-12-04 121 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。)