「ショート30 = 3 * 10」が正当な割り当てであるのはなぜですか?


102

が算術演算で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とaに値を割り当てることができないため、コンパイルshortは行われません。

数値リテラルについて何か特別なことはありますか?


23
short thirty = 10 * 3;ほとんどのshort thirty = 30;場合、有効なステートメントであるコンパイラによって置き換えられます。(ただし、関連するJLSセクションを調べる必要があります)。
Thomas

コンパイラー10 * 3は変数を計算し、結果を初期化します。実際に機能しない例では、JVMがshortをキャストする実行時に計算が行われます。
Felix

これは、stackoverflow.com / questions / 30346587 / java-char-to-byte- castingまたはstackoverflow.com/questions/9379983/…の複製だと思います。ただし、final int ten = 10; final int three = 3; short thirty = ten * three;正常にコンパイルされることに注意してください。
Marco13

7
If short is automatically promoted to int in arithmetic operations-それは関係ありません。どちら103ショートパンツはあるも、彼らが推進している、彼らはリテラルじゃないんです。
マシューは、

@MatthewRead:リテラルであっても、特定のデータ型として評価される必要がありますよね?だから、事実である103として評価されているintコンパイラによってsの?
LarsH

回答:


139

コンパイラはコンパイル時に10*3 30に置き換えられるためです。したがって、効果的には、コンパイル時に計算されます。short thirty = 10 * 3

tenand threeを変更してfinal short(コンパイル時定数をコンパイルして)、何が起こるかを確認してください:P

javap -v 両方のバージョン(10*3final short)に使用するバイトコードを調べます。違いはほとんどないことがわかります。

さて、ここでは、異なるケースのバイトコードの違いがあります。

ケース-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


17
好きなTry changing ten and three to final short運動:)
セルゲイ・パウク

1
@SergeyPauk-これは、コンパイル時の定数を理解する上で非常に重要です..すべてのプリミティブに適用されます(文字

1
@TheLostMindより良い言い回しのyou will see that there's no difference (between those two lines in the decompiled code)原因はこれがあなたの主張ではないことをお勧めしますか?
Sergey Pauk、2015

4
面白いことに、これcase 10*3:は、スイッチコンストラクトでも同様のことが合法であることも意味しています。
天井のGecko

5
そして同様に列挙型の構造体で。実際、ビットフィールドの列挙型定数に1 << 5のようなものを使用するのは慣用的です。
バトシェバ2015

18

はい、文字通りの場合に特別なことが起こってい10 * 3ます:コンパイル時に評価されます。したがって(short)、乗算されたリテラルを明示的に変換する必要はありません。

ten * three はコンパイル時に評価できないため、明示的な変換が必要です。

かどうかは別問題だろうtenthreeマークされましたfinal


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.