java条件运算符和不同类型

时间:2014-07-26 05:18:59

标签: java conditional-operator

我在Item班级中有两种方法:

public void setValue(String v);
public void setValue(Double v);

我想在另一个类中使用条件运算符setVAlue

String str = ...
Double dbl = ...
item.setValue((condition) ? str : dbl);

但是编译器说:

cannot find symbol
symbol  : method setValue(java.lang.Object&java.io.Serializable&java.lang.Comparable<? extends java.lang.Object&java.io.Serializable&java.lang.Comparable<?>>)

我认为编译器使用Double和String的最近的公共超类(超级接口)作为条件运算符的类型。但为什么呢?

3 个答案:

答案 0 :(得分:12)

因为做任何其他事情都没有任何意义。三元条件运算符必须返回某些特定类型的某些值 - 所有表达式必须在编译时中生成特定类型。此外,请注意,重载解析也在编译时发生。您在此处尝试调用的行为(后期绑定)在Java中不存在于此表单中。

表达式的类型必须与 true false 子表达式兼容。在这种情况下,最近的共同祖先类是Object,并且您没有setValue(Object)重载。

这是以工作方式重写内容的最简单方法:

if (condition) {
    item.setValue(str);
} else {
    item.setValue(dbl);
}

您还可以提供setValue(Object)重载,检查传递的对象类型并委托给相应的setValue()重载,如果类型不可接受则抛出异常。

答案 1 :(得分:2)

Java Language Specification

  

[...]

     

否则,第二个和第三个操作数是S1和S2类型   分别。设T1是应用装箱产生的类型   转换为S1,让T2成为应用产生的类型   拳击转换为S2。条件表达式的类型是   将捕获转换(第5.1.10节)应用于lub(T1, T2)的结果。

在您的情况下,我们将T1 StringT2视为Double

来自JLS,关于the least upper bound (lub)

  

一组引用类型的最小上限或“lub”是a   共享超类型比任何其他共享超类型更具体   (也就是说,没有其他共享超类型是最低级别的子类型   结合的)。

您可以继续阅读JLS以确定计算lub的确切方式,但从上面的定义我们可以看出编译器错误消息中提供的内容是有意义的。

请记住,三元运算符用作具有单个值的单个表达式。该值必须在编译时具有类型。因此,JLS必须为其指定规则。

这是一个相关的问题/答案

答案 2 :(得分:1)

如果您想使用三元运算符,只需按照代码即可解决您的问题。为了进行测试,我将false作为您可以放置​​条件表达式的默认值。

public class st1 {
    public static void main (String []args) {
        Item i = new Item();
        i.setValue (false?"test":0.0);
    }
}

class Item {
    private String str;
    private double d;
    public void setValue (Object str) {
        try {
            d = Double.parseDouble (str.toString());
            System.out.printf ("Double type : %f", d);
        } catch (NumberFormatException ne) {
            this.str = str.toString();
            System.out.printf ("String type : %s", this.str);
        }
    }
}