2013-01-02 19 views
10

最近、Javaでの基本的な算術演算に関するJavaの特質が気づきました。次のコードint - Javaの算術演算

byte a = 3; 
byte b = 4; 
byte c = a * b; 

で、私は「種類不一致」コンパイルエラーを取得...

intのプリミティブデータ型で実行するJavaでの基本的な算術演算(+-*/)です(long,doubleなど)であるのに対し、byteshortの算術演算は、最初にintにキャストされ、次に評価されます。

+0

良い質問。私は正直に答えを知らなかったが、これを見つけた。 http://mindprod.com/jgloss/multiplication.html – Zutty

答えて

15

操作はintに広がっています。

final byte a = 3, b = 4; 
byte c = a * b; // compiles 

final byte a = 3, b = 40; 
byte c = a * b; // compiles 

final int a = 3, b = 4; 
byte c = a * b; // compiles !! 

しかし

byte a = 3, b = 4; 
byte c = a * b; // doesn't compile as the result of this will be `int` at runtime. 

final byte a = 30, b = 40; 
byte c = a * b; // doesn't compile as the value is too large, will be an `int` 

ところでこれはオーバーフローにつながるにもかかわらず、コンパイルします。 :]

final int a = 300000, b = 400000; 
int c = a * b; // compiles but overflows, is not made a `long` 
+0

まあ、私は 'final'がここに違いを生むのを知りませんでした。とにかく、2番目の例でも 'a'と' b'はバイトとして宣言されているので、奇妙に見えます... コンパイラが値を決定できない限り、 – fge

+2

* **定数**範囲内にある式。 – assylias

7

整数演算の結果は、intまたはlongのいずれかです。これはJLSで綴られる:

4.2.2。整数演算

タイプint又はlongの値をもたらし、数値演算子、

  • 単項プラスとマイナス演算子+と - (§15.15.3、§15.15.4 )

  • 乗法演算子*、/、%、および(§15.17)

  • 添加演算子+と - ( 15.18)

  • ...

Also

5.6.2。ためにバイナリ数値昇格

オペレータが数値型に変換可能な値を表す必要がありそれぞれがオペランドの対、バイナリ数値昇格を適用し、次の規則が適用され、:

プリミティブ拡幅変換(5.1.2)は、以下の規則によって指定される一方または両方のオペランドを変換するために適用される:

  • 一方のオペランドがタイプdoubleの場合、他の二重に変換されます。

  • どちらのオペランドもfloat型の場合、もう一方はfloat型に変換されます。

  • どちらのオペランドもlong型の場合、他方はlongに変換されます。

  • それ以外の場合は、両方のオペランドがint型に変換されます。

...

バイナリ数値昇格は、特定の演算子のオペランドで実行されます。

  • 乗法演算子*、/および%(§15.17)

  • 数値型+および - (§15.18.2)の加算および減算演算子

  • 数値比較演算子<、< =、>、および> =(§15.20.1)

  • 数値等価演算子==と!=(§15.21.1)

  • 整数ビット単位演算子&、^、および| (§15.22.1)

  • 場合によっては、条件演算子? :値を決定することができるコンパイラが範囲内でなければ(15.25)bytecharshort