2017-10-25 69 views
3

Javaのプリミティブ型の宣伝について質問があります。次の例でわかるように、型不一致のエラーのためにメソッドの1つがコンパイルされません。各メソッドは同じ値を返しますが、異なる型を返します。プリミティブ型のプロモーション

プリミティブlongのバージョンはエラーなしで動作し、ラッパークラスLongのバージョンは失敗します。これは、returnステートメントのintリテラルが、より広範なプリミティブタイプ(たとえばlong)に、次に対応するラッパークラスIntegerなどにプロモートされるためです。 IntegerLongのサブクラスではないので、コンパイラはエラーを返します。

ラッパークラスByteのバージョンは何故エラーなく動作しますか?この時点でコンパイラは正確に何をしますか?

long getPrimitiveLong() { 
    return 12; // valid 
} 

Long getWrapperLong() { 
    return 12; // Error: type mismatch 
} 

Byte getWrapperByte() { 
    return 12; // valid 
} 
+0

'getWrapperLong'に対して' return 12L; 'を試したことがありますか?それは私のために働くようです。 – OldCurmudgeon

+0

はい、12Lまたは(長い)12で動作します。 –

答えて

5

いくつかのコンパイラの魔法を通じてByte作品とのバージョンのためのポスト次

読みます。

longとは異なり、接尾辞Lで構成することができます。 12Lbyteというリテラルはありません。そのため、Javaコンパイラは、バイトに収まる数値リテラルをリテラルとして扱います(byte)。したがって、最後の例の12は、タイプbyteの定数と見なされます。

Java Language Specificationは、セクション5.2でこの変換の説明を提供する:

変数のタイプである場合ボクシング変換続い狭くプリミティブ変換は を使用することができる。

  • Byteと定数式の値はタイプbyteで表されます。
  • Shortであり、定数式の値はタイプshortで表記できます。
  • Characterであり、定数式の値はタイプcharで表現可能です。
2

これは、Javaが1つの変換またはオートボックスを許可するためです。

Javaは、これらすべての操作を行うことができます。

int i = 5; 
double d = i; 
long l = i; 

またはAutoBoxの:二回の変換

Integer i = 5; 
Long l = 5L; 
Double d = 5.0; 

は、Javaに苦労を与えます。 12のような

0

数がエラー

は、あなたが長い変数の値の後のバイトと場所Lのためにキャストを使用することができますことを修正するには、なぜあるコンパイラによるデフォルトではint型として考えます。詳細

http://javaseeeedu.blogspot.com/2015/12/casting-part-1.html

0

簡単な答えとして、12を128に置き換えてみてください(バイトは-128から127の範囲です)。 コンパイルされません、そうですか? ここでの結果は、コンパイラがバイト境界を知っていることです。

詳細については、OpenJDKを参照してください。

関連する問題