![](/img/trans.png)
[英]Local Variable Type Inference with Conditional (Ternary) Operator of Different Types
[英]java conditional operator and different types
我在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 的最近公共超类(超级接口)作为条件运算符的类型。 但为什么?
因为做任何其他事情都没有任何意义。 三元条件运算符必须返回某些特定类型的值——所有表达式在编译时都必须产生特定类型。 此外,请注意重载解析也在编译时发生。 您尝试在此处调用的行为(后期绑定)在 Java 中以这种形式不存在。
表达式的类型必须与true和false子表达式兼容。 在这种情况下,最近的公共祖先类是Object
,并且您没有setValue(Object)
重载。
这是以工作方式重写现有内容的最简单方法:
if (condition) {
item.setValue(str);
} else {
item.setValue(dbl);
}
您还可以提供一个setValue(Object)
重载,用于检查传递的对象类型并委托给适当的setValue()
重载,如果类型不可接受则抛出异常。
[...]
否则,第二个和第三个操作数分别是 S1 和 S2 类型。 设 T1 为对 S1 应用装箱转换后的类型,设 T2 为对 S2 应用装箱转换后的类型。 条件表达式的类型是将捕获转换(第 5.1.10 节)应用于
lub(T1, T2)
。
在您的情况下,让我们将T1
设为String
,将T2
设为Double
。
从 JLS,关于最小上限 (lub)
一组引用类型的最小上限或“lub”是一个共享超类型,它比任何其他共享超类型更具体(也就是说,没有其他共享超类型是最小上限的子类型)。
您可以继续阅读 JLS 以计算 lub 的确切计算方式,但从上面的定义我们可以看到编译器错误消息中提供的内容是有道理的。
请记住,三元运算符用作具有单个值的单个表达式。 该值在编译时必须具有类型。 因此,JLS 必须为其指定规则。
这是一个相关的问题/答案
如果您想使用三元运算符,则仅使用以下代码即可解决您的问题。 为了测试,我将 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);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.