我正在为数字创建一个简单的包装类。简单地说,我希望它显示值42
和42.0
;然而,它应该显示值1.6180338
作为该数字。只是不够。
private double number;
...
@Override
public String toString() {
return String.valueOf(
number == longValue()
? longValue()
: number );
}
...
@Override
public long longValue() {
return (long) number;
}
private double number;
...
@Override
public String toString() {
return String.valueOf(
number == longValue()
? longValue()
: number );
}
...
@Override
public long longValue() {
return (long) number;
}
问题是42.0
的值总是显示而不是 toString(...)
方法中正确的42
值
尽管String.valueOf(...)
方法有很多重载方法来将正确的原语值显示为字符串,但在使用哪个重载方法上存在歧义。它可以使用String.valueOf(double)
或String.valueOf(long)
。这是因为三元操作符语句和结果类型有关。
我认为编译器能够识别long
类型并调用适当的String.valueOf(long)
方法。情况似乎并非如此;相反,JVM将在编译时选择最安全但限制最大的重载方法。在本例中,它是String.valueOf(double)
,因为它可以安全地将long
转换为double
。
我知道这在Java中是不可能的,但是类似的东西在其他语言中是可用的吗?是否有某种定义来解释这个方法,您能更详细地解释一下吗?
我指的是像Covariance
或Contra-variance
这样的定义。注意:我意识到定义不是这两个中的一个:)
由于Java是静态类型语言,三元操作符的结果必须具有在编译期间定义的显式类型,以便编译器可以继续处理外部表达式。由于ternary的两个分支都是数字,因此它们被提升为JLS 15.25和5.6.2中描述的更精确的类型。您可以解决将参数强制转换为对象的问题:
return String.valueOf(
number == longValue()
? (Object)longValue()
: (Object)number );
这样你将把数字框起来,并使用String.valueOf(Object)
,这对两个分支都很好。