代码之家  ›  专栏  ›  技术社区  ›  Farvardin

java条件运算符和不同类型

  •  5
  • Farvardin  · 技术社区  · 10 年前

    我有两种方法 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 回复  |  直到 4 年前
        1
  •  13
  •   cdhowie    10 年前

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

    表达式的类型必须与 真的 假的 子表达式。在本例中,最近的公共祖先类是 Object ,而你没有 setValue(Object) 超载。

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

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

    您还可以提供 setValue(对象) 重载,用于检查传递的对象的类型,并将其委托给适当的 setValue() 重载,如果类型不可接受,则引发异常。

        2
  •  2
  •   Community arnoo    7 年前

    这个 Java Language Specification

    [...]

    否则,第二和第三操作数的类型为S1和S2 分别地设T1为应用装箱产生的类型 转换为S1,并设T2为应用 装箱转换为S2。条件表达式的类型为 将捕获转换(§5.1.10)应用于 lub(T1, T2) .

    在你的情况下,让我们采取 T1 成为 String T2 成为 Double .

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

    一组引用类型的最小上界或“lub”是 比任何其他共享超类型更具体的共享超类型 (也就是说,没有其他共享超类型是最小上超类型的子类型 绑定)。

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

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

    这里有一个相关的问题/答案

        3
  •  1
  •   iammurtaza    10 年前

    如果您想使用三元运算符,只有以下代码才能解决您的问题。对于测试,我将false设置为默认值,您可以将条件表达式设置为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);
            }
        }
    }