(例えば~
など)単項および二項演算子のJava対象におけるそれぞれ"unary numeric promotion" (JLS, Section 5.6.1)と"binary numeric promotion" (JLS, Section 5.6.2)にそのオペランド、「第一少なくともint
観光を促進する」ための空想の用語。上方連結JLSセクションを引用単項数値昇格のための具体的
、:
いくつかの演算子は、数値型の値を生成しなければならない単一オペランドに単項数値昇格適用:
を
と
...オペランドがコンパイル時の型バイト、短い、またはcharである場合、それは拡大プリミティブ変換によってint型の値に昇格される(§ 5.1.2)。
(バイナリ数値昇格は、両方のオペランドを操作する、同様です。)
ので、b
がbyte
場合でも、b
の値が第一int
に昇進したので~b
は、int
あります。
ソリューション:byte
に戻ってそれをキャスト:
b = (byte) (~b);
なぜ、Javaの?
それでは、その理由は何ですか?私が見つけることができる演算子、byte
s、short
s、およびchar
で動作するためのJVMバイトコード命令が存在しないようです。たとえば、使用している単項ビット補数演算子(〜)is implemented as an "XOR" operation with -1
(all bits set)。そのリンクから:
tempSpock &= ~mask;
25 iload_2 // Push local variable 2 (mask).
26 iconst_m1 // Push -1.
27 ixor // Bitwise EXCLUSIVE-OR top two ints: ~mask
しかし、私はできだけfind instructions for XOR(および他の単項および二項演算子のためにあまりにも)int
sおよびlong
のための(float
とdouble
バージョンになり、他の事業者のために存在します適切な場において)。
したがって、byte
、short
、またはchar
にこれらの操作を実行するためのバイトコード命令がないため、Javaはこれらのプロモーションを実行する必要があります。
なぜ、JVMですか?
これは別の質問をもたらします。なぜ、JVMはそのようなバイトコード命令をサポートしていませんか?答えは、「1バイトの命令セットですべてをエンコードするにはあまりにも多くのものがあるからです」と思われます。 JVM Specification, Section 2.11.1によると、
は、Java仮想マシンの
1バイトのオペコードサイズ、その命令セットの設計上のオペコードの場所の圧力へのエンコードの種類を考えます。各型付き命令がすべてのJava仮想マシンの実行時データ型をサポートする場合、
は、バイトで表現できる命令以上の命令があります。代わりに、Java仮想マシンの命令セットは、特定の操作に対してタイプサポートのレベルを低下させます。換言すれば、命令セットは意図的に直交していない。サポートされていないデータ型とサポートされているデータ型を必要に応じて変換するには、別の命令を使用できます。
(強調鉱山)
結論として、JVMの一バイトコード命令セットは、単項数値昇格し、二項数値昇格を必要と、バイトコードbyte
S上のほとんどの操作のための指示、char
S、およびshort
Sを排除。
おそらく、コンピュータは少なくとも32ビット長のレジスタ全体に対して演算を実行する必要があるからです。 – user2573153
うん!それが理由かもしれません。 –