java中的new long(1)_关于java:Code对象o = true吗? new Integer(0):new Long(1)返回值为0的Long。为什么?...

本问题已经有最佳答案,请猛点这里访问。

请考虑以下代码:

Object obj = true ? new Integer(0) : new Long(1);

System.out.println(obj.getClass() +"

value =" + obj);

其结果是:

class java.lang.Long

value = 0

代替:

class java.lang.Integer

value = 0

有人可以澄清为什么我们在Java中具有这种功能吗? 对我来说很奇怪。

您是否有任何示例在其中可能有用?

更新:

这是一段字节码,我们可以看到那里发生了什么

NEW java/lang/Integer

DUP

LDC"0"

INVOKESPECIAL java/lang/Integer. (Ljava/lang/String;)V

INVOKEVIRTUAL java/lang/Integer.intValue ()I

I2L

INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long;

ASTORE 1

为了使三元语句有效,双方应返回相同类型的值

@PeterLawrey Object o = false ? new Long(0) : new Integer(1);也将返回class java.lang.Long和1。 它不是最后一个参数的类型,而是可以通过扩展接收的类型。

当经过认真研究的问题获得很多好评时,我会喜欢上它。 但是如今阅读JLS实在是太多了...

为了澄清,这是为什么三元运算符意外地转换整数?的重复,而不是另一个。

另请参阅stackoverflow.com/questions/25230171/和稍微相关的stackoverflow.com/questions/8098953/

这是怎么回事

二进制数值提升将您的Integer和Long类型转换为Long,以用作应用于条件运算符表达式的通用类型

拆箱那些包装对象

然后装箱条件表达式的结果值

条件运算符的第二和第三操作数必须最终具有相同的类型,这是表达式的结果类型。 Integer和Long当然不是相同的类型。

但是,如JLS§15.25中所述,在确定可能应用于表达式的通用类型时,编译器将应用二进制数值提升。该部分具有方便的表15.25-D,该表告诉我们,当第二个操作数的类型为Integer而第三个操作数的类型为Long时,编译器将对Integer,Long进行二进制数值提升。 Integer,Long上的二进制数值提升产生Long。因此,条件运算符表达式的结果为Long。

由于表达式的结果类型为Long,因此必须将Integer或Long取消装箱(在Integer的情况下进行强制转换)。

最后,将其分配给Object,这将强制装箱并将Long包裹在Long中。因此,您最终得到一个包含值0的Long,该值与您的输出匹配。

如此有效,如果我们忽略了以下事实,由于代码中的true(我在下面使用了flag),编译器将处理以下常量表达式,因为它处理的是常量表达式,该代码最终将这个:

Object obj = Long.valueOf(flag ? (long)(new Integer(0)).intValue() : (new Long(1)).longValue());

System.out.println(obj.getClass() +"

value =" + obj);

(long)(new Integer(0)).intValue()表示将Integer拆箱并将其强制转换为Long,因此它与表达式结果类型匹配。

(new Long(1)).longValue()表示将Long拆箱,因此它与表达式结果类型匹配。

Long.valueOf表示最后的拳击。

JLS-15.25中对此行为进行了很好的解释。条件运算符? ::

The conditional operator has three operand expressions. ? appears between the first and second expressions, and : appears between the second and third expressions.

[...]

The type of a conditional expression is determined as follows:

[...]

Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:

[...]

Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.

这与三元运算符的工作方式有关。

:两侧的操作数必须具有兼容的类型,因此您不能具有以下类型:

true ? 1 :"Hello"

由于int和String不能隐式地相互转换。

但是,根据您的情况,类型是兼容的! int可以隐式转换为Long。这就是编译器所做的!它看到一个int和long,并决定该表达式应求值为Long。它将两个值拆箱,并将int隐式转换为Long。最后,它将结果Long装箱,使其变为Long并将其放入变量中。

实际上long可以存储整数的值,但integer不能存储long的值(概念正在扩展),并且您将其存储在Object中,这就是为什么将其存储在Long中的原因。内部也使用装箱和拆箱

可能的编译器代码:

Long obj = true ? new Integer(0) : new Long(1);

System.out.println(obj.getClass()+" nvalue =" + obj);

无效的代码(无法编译):

Integer obj = true ? new Integer(0) : new Long(1);

System.out.println(obj.getClass()+" nvalue =" + obj);

自己检查一下,让我知道是否有任何疑问。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值