1. タイプキャスト
プリミティブ型の変数 (型を除くboolean
) は、さまざまな型の数値を格納するために使用されます。変数の型は変更されませんが、ある型から別の型に変換できる場所があります。そしてその場所は割り当てです。
異なる型の変数を相互に割り当てることができます。これを行うと、ある型の変数の値が別の型の値に変換され、2 番目の変数に割り当てられます。この点に関して、拡張と縮小という 2 種類の型変換を識別できます。
拡大は、値を小さなバスケットから大きなバスケットに移動することに似ています。この操作はシームレスで痛みがありません。絞り込みは、値を大きなバスケットから小さなバスケットに移動するときに発生します。十分なスペースがない可能性があり、何かを破棄する必要があります。
バスケットのサイズ別に分類したタイプは次のとおりです。
2. 型変換の拡張
多くの場合、ある数値型の変数を別の数値型の変数に割り当てることが必要になります。どうやってそれを行うのですか?
Java には 4 つの整数型があります。
タイプ | サイズ |
---|---|
byte |
1 byte |
short |
2 bytes |
int |
4 bytes |
long |
8 bytes |
小さいバスケットに格納されている変数は、いつでも大きいバスケットに格納されている変数に割り当てることができます。
int
、変数への代入short
もbyte
簡単に行えますlong
。short
変数を変数byte
に代入することもできますint
。また、byte
変数には変数を割り当てることができますshort
。
例:
コード | 説明 |
---|---|
|
このコードは問題なくコンパイルされます。 |
このような、小さい型から大きい型への変換は、拡張型変換と呼ばれます。
実数についてはどうでしょうか?
彼らにとってはすべてが同じであり、サイズが重要です。
タイプ | サイズ |
---|---|
float |
4 bytes |
double |
8 bytes |
float
double
変数には問題なく代入できます。しかし、整数型ではさらに興味深いことが起こります。
任意の整数変数をfloat
変数に割り当てることができます。型もlong
8 バイト長です。そして、任意の整数変数またはfloat
変数をdouble
変数に割り当てることができます。
コード | ノート |
---|---|
|
|
実数型に変換すると、十分な有効桁数が不足するため精度が失われる可能性があることに注意してください。
整数から浮動小数点数に変換する場合、数値の下位部分が切り捨てられることがあります。ただし、小数は近似値を格納すると理解されているため、そのような代入演算は許可されます。
3. 型の縮小変換
他の可能性についてはどうでしょうか? long
変数に値を代入する必要がある場合はどうすればよいでしょうかint
?
変数をバスケットとして想像してください。1、2、4、8 バイトなど、さまざまなサイズのバスケットをご用意しています。リンゴを小さなカゴから大きなカゴに移すのは問題ありません。しかし、大きなかごから小さなかごに移すと、リンゴの一部が失われる可能性があります。
より大きな型からより小さな型へのこの変換は、縮小型変換と呼ばれます。このような代入操作を実行する場合、数値の一部が新しい変数に適合しないため、破棄される可能性があります。
型を絞り込むときは、間違いではないこと、数値の一部を意図的に破棄していることをコンパイラに明示的に伝える必要があります。これには、型キャスト演算子が使用されます。括弧内は型名です。
このような状況では、Java コンパイラはプログラマにタイプキャスト演算子を指定することを要求します。一般に、次のようになります。
(type) expression
例:
コード | 説明 |
---|---|
|
毎回、型キャスト演算子を明示的に指定する必要があります |
ここでa
は に等しいので1
、型キャスト演算子は過剰に思えるかもしれません。しかし、a
もっと大きかったらどうでしょうか?
コード | 説明 |
---|---|
|
|
100 万はlong
と に完全に収まりますint
。ただし、変数に 100 万を割り当てる場合short
、最初の 2 バイトは破棄され、最後の 2 バイトのみが保持されます。そして、 に代入するとbyte
、残るのは最後のバイトだけです。
メモリ内での数値の配置方法:
タイプ | 2進数表記 | 10進数表記 |
---|---|---|
int |
0b 00000000 00001111 01000010 01000000 | 1000000 |
short |
0b 01000010 01000000 | 16.960 |
byte |
0b 01000000 | 64 |
char
タイプ
a はchar
、 a と同様にshort
2 バイトを占有しますが、一方を別のものに変換するには、常に型キャスト演算子を使用する必要があります。ここでの問題は、型が符号付きで~ のshort
値を含めることができるのに対し、型は符号なしで~ の値を含めることができることです。-32,768
+32,767
char
0
65,535
負の数は に格納できませんchar
が、 に格納することはできますshort
。また、 にはshort
より大きい数値を格納できません32,767
が、そのような数値は に格納できますchar
。
4. 式の種類
異なる型の変数が同じ式で使用されている場合はどうなるでしょうか? 論理的には、最初に共通の型に変換する必要があることがわかります。しかし、どれでしょうか?
もちろん、より大きなものに。
Java は常に、より大きな型に変換します。大まかに言うと、まず型の 1 つが拡張され、その後初めて同じ型の値を使用して操作が実行されます。
anint
と a がlong
式に含まれている場合、 の値はint
a に変換されてlong
からのみ操作が続行されます。
コード | 説明 |
---|---|
|
a は a に拡張されlong 、加算が行われます。 |
浮動小数点数
式に整数と浮動小数点数 (float
または) が含まれる場合、整数は浮動小数点数 (または) に変換され、その後でのみ演算が実行されます。double
float
double
操作に afloat
と a が含まれる場合double
、 はfloat
に変換されますdouble
。これは実際に期待されています。
、byte
、short
および型は、相互に対話するときにchar
常に に変換されます。int
この型が標準の整数型とみなされるのには十分な理由がありますint
。
byte
aと a を乗算するとshort
、 が得られますint
。byte
aと a を乗算するとbyte
、 が得られますint
。byte
aと a を追加してもbyte
、 が得られますint
。
これにはいくつかの理由があります。例:
コード | 説明 |
---|---|
|
110 * 120 これは13,200 、次の型の最大値よりわずかに大きい値ですbyte 。127 |
|
110 + 120 は であり230 、これも次の型の最大値よりわずかに大きくなりますbyte 。127 |
一般に、8 ビット (1 バイト) の数値と 8 ビット (1 バイト) の数値を乗算すると、16 ビット (2 バイト) を占める数値が得られます。
その結果、 より小さい整数型のすべての演算は、int
常に直ちにint
s に変換されます。つまり、 より小さい型の変数に計算結果を格納したい場合は、int
常に型キャスト演算子を明示的に指定する必要があります。
例:
コード | 説明 |
---|---|
|
式byte * byte は次のようになります。int |
|
式byte + byte は次のようになります。int |
|
式byte + int は になります。int リテラルのものは です int 。 |
5. 重要なニュアンス
型キャスト演算子はかなり高い優先順位を持っています。
つまり、式にたとえば加算とタイプキャスト演算子が含まれる場合、加算の前にタイプキャストが実行されます。
例:
コード | 説明 |
---|---|
|
タイプキャスト演算子はa 、すでに である変数にのみ適用されますbyte 。このコードはコンパイルされません。 |
|
これが正しい方法です。 |
式の 1 つのコンポーネントだけではなく、式全体を特定の型に変換する場合は、式全体をかっこで囲み、前にタイプキャスト演算子を置きます。
GO TO FULL VERSION