它只是查看字节码,您会看到(只需修改您的示例)
Number n = true ? new Long(166666) : new Double(24444.0);
System.out.println(Boolean.toString(n instanceof Long));
System.out.println(Boolean.toString(n instanceof Double));
字节码
_new 'java/lang/Long'
dup
ldc 166666
invokespecial 'java/lang/Long.<init>','(J)V'
invokevirtual 'java/lang/Long.longValue','()J'
l2d
invokestatic 'java/lang/Double.valueOf','(D)Ljava/lang/Double;'
astore 1
重点是l2d
它使下一步
从堆栈中弹出一个长整数,将其转换为双精度浮点数,然后将双精度数推回堆栈。请注意,这可能会导致精度损失(double 的有效位是 54 位,而 long 是 64 位),但不会损失幅度(因为 double 的范围大于 long 的范围)。使用 IEEE 754 舍入到最近模式进行舍入。
在这一切都很好之后,你将拥有Double实例,但具有Long Value!如果您在 Debug 模式下查看,您会看到我们的数字是 Double 但值来自 Long,它在上面的字节码中描述
我们可以在字节码中看到它
getstatic 'java/lang/System.out','Ljava/io/PrintStream;'
aload 1
_instanceof 'java/lang/Long'
invokestatic 'java/lang/Boolean.toString','(Z)Ljava/lang/String;'
invokevirtual 'java/io/PrintStream.println','(Ljava/lang/String;)V'
getstatic 'java/lang/System.out','Ljava/io/PrintStream;'
aload 1
_instanceof 'java/lang/Double'
invokestatic 'java/lang/Boolean.toString','(Z)Ljava/lang/String;'
invokevirtual 'java/io/PrintStream.println','(Ljava/lang/String;)V'
return