算術演算でshort
がint
に自動的に昇格される場合、その理由は次のとおりです。
short thirty = 10 * 3;
short
変数thirty
?への正当な割り当て
次に、これ:
short ten = 10;
short three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED
これと同様に:
int ten = 10;
int three = 3;
short thirty = ten * three; // DOES NOT COMPILE AS EXPECTED
int
値をshort
に割り当てることは期待どおりにキャストしないと許可されないため、コンパイルされません。
数値リテラルについて何か特別なことが起こっていますか?
コンパイラは10*3
をcompile time自体で30に置き換えるためです。したがって、効果的に:short thirty = 10 * 3
はコンパイル時に計算されます。
ten
とthree
をfinal short
に変更して(コンパイル時定数に変更してください)、何が起こるかを確認してください:P
両方のバージョン(javap -v
と10*3
)のfinal short
を使用してバイトコードを調べます。ほとんど違いがないことがわかります。
OK、だから、ここに異なるケースのバイトコードの違いがあります。
ケース-1:
Javaコード:main(){short s = 10 * 3; }
バイトコード:
stack=1, locals=2, args_size=1
0: bipush 30 // directly Push 30 into "s"
2: istore_1
3: return
ケース-2:
public static void main(String arf[]) {
final short s1= 10;
final short s2 = 3;
short s = s1*s2;
}
バイトコード:
stack=1, locals=4, args_size=1
0: bipush 10
2: istore_1
3: iconst_3
4: istore_2
5: bipush 30 // AGAIN, Push 30 directly into "s"
7: istore_3
8: return
ケース-3:
public static void main(String arf[]) throws Exception {
short s1= 10;
short s2 = 3;
int s = s1*s2;
}
バイトコード:
stack=2, locals=4, args_size=1
0: bipush 10 // Push constant 10
2: istore_1
3: iconst_3 // use constant 3
4: istore_2
5: iload_1
6: iload_2
7: imul
8: istore_3
9: return
上記の場合、10
および3
はローカル変数s1
およびs2
から取得されます
はい、リテラルの場合には特別なことが行われます:10 * 3
はcompileの時点で評価されます。したがって、乗算されたリテラルに対して明示的な(short)
変換は必要ありません。
ten * three
はコンパイル時に評価できないため、明示的な変換が必要です。
ten
とthree
がfinal
とマークされている場合は、別の問題になります。