なぜ「int i = 2147483647 + 1;」なのか OK、しかし「バイトb = 127 + 1;」コンパイルできませんか?


126

なぜint i = 2147483647 + 1;問題byte b = 127 + 1;ないのですが、コンパイルできませんか?


16
私にも本当の疑いがあります。なぜbyteデータ型がそんなに苦痛なのでしょうか。
BoltClock

9
byte署名されていないのではなく、署名されているのは間違いなく設計ミスです。
11

4
@BoltClockそれを適切に使用する方法を知らないときだけそれは苦痛です。stackoverflow.com/questions/397867/...
starblue

2
@ starblue、Javaバイト型を適用できる実際の例はありますか?
–ThorbjørnRavn Andersen、2011

バイトとして指定されているデータがある場合はbyte、パラメータなどでわかりやすくするためにJava を使用します。その場合、int値を割り当てることができないという事実は、いくつかのバグを捕らえることさえあります。またはbyte、配列のスペースを節約するために使用します。byteたまたまバイトに収まる単一の値には使用しません。
starblue

回答:


172

定数はそう、int型として評価されている2147483647 + 1オーバーフローして、あなたに割り当て可能にした新しいint型、与えintながら、127 + 1またとして評価intに等号を128、そしてそれがに割り当て可能ではありませんbyte


10
実際、今日私はそれについてのパズルを含むいくつかのJavaパズルを読みました...ここを参照してください:javapuzzlers.com/java-puzzlers-sampler.pdf-パズル3
MByD

3
問題は、intバイナリ数値プロモーションによるタイプで、値127はレッドニシンです。
starblue

定数が無限の精度で評価され、int i = 2147483647 + 1でエラーが発生することを好みます。
エドゥアルド

@MByD:「while 127 + 1 also evaluated as int equals to 128, and it is not assignable to byte.」とおっしゃったように、これは50 + 1が次のように評価されbyte、割り当て可能なことを意味しbyteますか?
ブシャン

1
@ 10101010-正確ではない。これはバイトに割り当て可能ですが、最初に(標準に従って)intとして評価されます。
MByD '27 / 10/27

35

リテラル127は、int型の値を示します。リテラル1もそうです。これら2つの合計は整数128です。2番目の場合の問題は、これをバイト型の変数に割り当てることです。式の実際の値とは関係ありません。強制(*)をサポートしないJavaに関係しています。タイプキャストを追加する必要があります

byte b = (byte)(127 + 1);

そしてコンパイルします。

(*)少なくともString-to-integer、float-to-Time、...の種類ではありません。Javaは、ある意味で非損失(Javaはこれを「拡大」と呼びます)であれば強制をサポートします。

いいえ、「強制」という言葉は修正する必要がありませんでした。それは非常に故意にそして正しく選ばれました。手元に最も近いソースから(Wikipedia):「ほとんどの言語では、コンパイル時または実行時のいずれかに暗黙の変換を示すために強制型変換という単語が使用されます。」また、「コンピュータサイエンスでは、型変換、型キャスト、および強制は、暗黙的または明示的に、あるデータ型のエンティティを別のデータ型に変更するさまざまな方法です。」


コードの例は、おそらくバイトb =(byte)127 + 1です。これは「最大値のバイト値に1を加える」であり、例では128のint値をバイト値に変換します。
NKCSS、2011

6
@NKCSS-私はあなたが正しいとは思いません、これ-128 (byte)(127 + 1)(整数)をバイトに(byte)127 + 1キャストしますが、これは127をバイトにキャストしますが、1(int)に追加されているため、再びintにキャストします。 128(int)を取得し、エラーは残ります。
MByD 2011

6

@MByDへの証拠として:

次のコードがコンパイルされます。

byte c = (byte)(127 + 1);

なぜなら、式(127 + 1)はintであり、スコープオフbyteタイプを超えていますが、結果はにキャストされるからbyteです。この式はを生成し-128ます。


3

JLS3#5.2割り当て変換

(変数=式)

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

変数のタイプがバイト、ショート、または文字であり、定数式の値が変数のタイプで表現可能な場合は、ナローイングプリミティブ変換を使用できます。


この句がないと、次のように書くことはできません。

byte x = 0;
char c = 0;

しかし、これを行うことができるでしょうか?私はそうは思いません。プリミティブ間の変換にはかなりの魔法があり、非常に注意が必要です。私は書くために邪魔になりました

byte x = (byte)0;

質問については、できることは...本当に何も問題はないbyte x = 0と思いますが、それでも、私はCプログラマーです。
Gradyプレーヤー

char c = 0に対する引数が見られるかもしれませんが、なぜバイトx = 0が間違っているのですか?
Michael Burge、2011

彼らはバイト変数にバイト0を割り当てていると考えて、訓練されていない目を誤解させます。この例ではそれほど害はありませんが、一般的に、バイト/ショート/文字での操作は、暗黙的な変換のために非常に混乱する可能性があります。彼らは人々が考えるよりもはるかに複雑です。私はコードをできるだけ明確にしたいのですが、いくつかのキーストロークを節約するために不確実性を導入しないでください。
評判の悪い2011

ナローイングプリミティブの変換がlongからintへの変換、たとえばint i = 1 + 0Lの場合も同様の規則が適用されますか?引用したテキストがそのケースを明示的に除外しているので、質問してください。
Erwin Smout、2011

@アーウィンいいえ、int i=0L違法です。
評判の悪い2011
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.