単純にバイトコードを見るとわかります(単に例を変更しただけです)
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
、次のステップを作成することです
long 整数をスタックからポップし、倍精度浮動小数点数にキャストして、倍精度浮動小数点数をスタックにプッシュします。これにより、精度が失われる可能性があります (double の有効桁数は long の 64 ビットに対して 54 ビットです) が、大きさが失われることはありません (double の範囲は long の範囲よりも大きいため)。丸めは、IEEE 754 round-to-nearest モードを使用して行われます。
そして、この後はすべて良いので、Doubleインスタンスがありますが、Long Valueがあります! デバッグ モードで見ると、数値は 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