8

コンパイラの特定の機能が私を困惑させます (Eclipse を使用する Oracle JDK 1.7)。

したがって、char プリミティブは明示的に short と byte にキャストする必要があると書かれているこの本を持っていますが、データ型の許容範囲が重複しないため、これはすべて理にかなっています。

つまり、以下のコードは機能します (ただし、明示的な型キャストがないと機能しません)。

char c = '&';  
byte b = (byte)c;
short s = (short)c;

b または s を印刷すると、数値 38 が正しく表示されます。これは、Unicode の (&) に相当する数値です。

それが私の実際の質問につながります。以下も同様に機能するのはなぜですか?

byte bc = '&';
short sc = '&';
System.out.println(bc); // Correctly displays number 38 on the console
System.out.println(sc); // Correctly displays number 38 on the console

今、私は確かに次のことを理解しています(これも機能します):

byte bt = (byte)'&';
System.out.println(bt); // Correctly displays number 38 on the console

しかし、このコンパイラ警告なしの文字からバイト (および短い) への「こっそり変換」は、私には正しくないようです。

なぜこれが許可されているのか、誰か説明できますか?

理由は'<char>'それ自体の解釈にある可能性があるため、実際には char プリミティブ状態にはなりませんが、数値 (8 進数または 16 進数など) 値として処理されますか?

4

5 に答える 5

8

基本的に、代入変換の仕様は

さらに、式が byte、short、char、または int 型の定数式 (§15.28) である場合:

変数の型が byte、short、または char であり、定数式の値が変数の型で表現できる場合は、縮小プリミティブ変換を使用できます。

あなた'&'はまさに「byte、short、char、またはint型の定数式」です。

于 2013-06-12T10:51:31.047 に答える
7

これは、コンパイル時の定数の絞り込みと呼ばれます。Java 言語仕様のセクション 5.2 で説明されています。

コンパイル時の定数の絞り込みは、次のようなコードを意味します。

byte theAnswer = 42;

許可されています。縮小がなければ、整数リテラル 42 の型が int であるという事実は、byte へのキャストが必要になることを意味します。

文字リテラルについても同様です。値が a に収まる場合、byte変換は必要ありません。値が収まらない場合は、キャストする必要があります。そうしないと、コンパイル エラーが発生します。

たとえば、これはコンパイルされません。

byte bc = '\uff12'; // Does not compile without a cast

しかし、これはうまくコンパイルされます:

byte bc = (byte)'\uff12';
于 2013-06-12T10:52:23.720 に答える
1

この説明で十分かどうかはわかりませんが、この動作は JLS で定義されています。JLS のセクション 5.2から:

さらに、式が byte、short、char、または int 型の定数式 (§15.28) である場合:

  • 変数の型が byte、short、または char であり、定数式の値が変数の型で表現できる場合は、縮小プリミティブ変換を使用できます。
  • 変数の型が次の場合、縮小プリミティブ変換とそれに続くボックス化変換を使用できます。
    • バイト型と定数式の値はバイト型で表現可能です。
    • Short であり、定数式の値は short 型で表現できます。
    • 文字と定数式の値は char 型で表現できます。
于 2013-06-12T10:51:01.593 に答える
1

以下も同様に機能するのはなぜですか?

'&'は値が に収まる定数式であるためですbyte

JLS 14.4.2

宣言子に初期化式がある場合、式が評価され、その値が変数に割り当てられます。

JLS5.2

代入変換は、式の値が変数に割り当てられる (§15.26) ときに発生します。式の型を変数の型に変換する必要があります。

....

さらに、式が byte、short、char、または int 型の定数式 (§15.28) である場合:

  • 変数の型が byte、short、または char であり、定数式の値が変数の型で表現できる場合は、縮小プリミティブ変換を使用できます。
于 2013-06-12T10:45:36.963 に答える
0

変数 bc の初期化子にある式 '&' は定数式です。変数 b および s の初期化子にある式 c は、定数式ではありません。Java は、値が定数式のみの結果である場合にコンテキストが必要とする場合に、プリミティブの暗黙的な縮小変換を実行します。

于 2013-06-12T10:51:23.063 に答える