JavaRush /Java Blog /Random-JA /Java でのプリミティブ型のキャスト (変換)

Java でのプリミティブ型のキャスト (変換)

Random-JA グループに公開済み
こんにちは!JavaRush を使用しているときに、プリミティブ型に何度も遭遇しました。これらについて私たちが知っていることの短いリストは次のとおりです。
  1. これらはオブジェクトではなく、メモリに格納されている値を表します。
  2. プリミティブ型にはいくつかの種類があります。
    • 整数 - byteshortintlong
    • 浮動小数点数 (小数) -floatおよびdouble
    • ブール値 -boolean
    • 記号 (文字と数字を示すため) -char
  3. それぞれに独自の値の範囲があります。
プリミティブ型 メモリ内のサイズ 値の範囲
バイト 8ビット -128~127
短い 16ビット ~ -32768 ~ 32767
チャー 16ビット 0から65536まで
整数 32ビット -2147483648 から 2147483647
長さ 64ビット -9223372036854775808 から 9223372036854775807
浮く 32ビット (2の-149乗)から((2-2の-23乗)*2の127乗)
ダブル 64ビット (-2 の 63 乗) から ((2 の 63 乗) - 1)
ブール値 8 (配列で使用する場合)、32 (配列以外で使用する場合) 正しいか間違っているか
ただし、値に加えて、型によってメモリ サイズも異なります。 int以上かかりますbyte。A long- 以上short。プリミティブによって占有されるメモリの量は、入れ子人形と比較できます。 プリミティブ型の拡張と縮小 - 2 入れ子人形の内部には空き領域があります。入れ子人形が大きいほど、より多くのスペースが得られます。大きな入れ子人形の中にlong小さな人形を簡単に入れることができますint。簡単にフィットし、余分なことをする必要はありません。Java では、プリミティブを操作するとき、これを自動変換と呼びます。別の言い方では拡張機能とも呼ばれます。簡単な拡張例を次に示します。
public class Main {

   public static void main(String[] args) {

       int bigNumber = 10000000;

       byte littleNumber = 16;

       bigNumber = littleNumber;
       System.out.println(bigNumber);
   }
}
byteここでは、変数に 値を代入しますint。割り当ては成功し、何の問題もありませんでした。 に格納された値は、 にbyte「収まる」よりも少ないメモリ領域を占有しましたint。「小さな入れ子人形」 (値byte) は、「大きなマトリョーシカ」 (変数int) に簡単に収まります。逆に、そのようなサイズ向けに設計されていない変数に大きな値を入れようとする場合は、別の問題になります。原則として、このトリックは実際の入れ子人形では機能しませんが、Java では機能しますが、微妙な違いがあります。int変数に値を入れてみましょうshort
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = bigNumber;//error!
   System.out.println(bigNumber);
}
エラー!コンパイラは、あなたが何か非標準的なことをしようとしていることを理解し、int小さなマトリョーシカ人形 ( ) の中に大きなマトリョーシカ人形 ( ) を入れますshort。この場合のコンパイル エラーは、コンパイラからの次のような警告です。「確信がある場合は、コンパイラーにそのことを伝えてください。「すべて問題ありません。何をしているのかわかりました!」このプロセスは、明示的な型変換、または縮小と呼ばれます。絞り込みを行うには、値をキャストする先の型を明示的に指定する必要があります。言い換えれば、コンパイラーの質問に答えます。「それでは、この大きな人形をこれらの小さな人形のどれに入れますか?」私たちの場合、次のようになります。
public static void main(String[] args) {

   int bigNumber = 10000000;

   short littleNumber = 1000;

   littleNumber = (short) bigNumber;
   System.out.println(littleNumber);
}
値をint変数に当てはめてshort、その変数に対して責任を負いたいことを明示的に示しました。コンパイラは、より狭い型の明示的な指示を確認して、変換を実行します。結果はどうなるでしょうか? コンソール出力: -27008 ちょっと予想外です。なぜまさにこのようなのでしょうか?実は簡単なんです。元の値は 10000000 でした。これは 32 ビットを占める変数に格納されておりint、バイナリ形式では次のようになります。 プリミティブ型の拡張と縮小 - 3 この値を変数に書き込みますshortが、格納できるのは 16 ビットだけです。したがって、数値の最初の 16 ビットのみがそこに移動され、残りは破棄されます。結果として、変数にはshort値 が含まれます プリミティブ型の拡張と縮小 - 4。この値は、10 進数形式では -27008 とまったく同じです。そのため、コンパイラは特定の型への明示的なキャストの形式で「確認を求めました」。まず、結果に対して責任を負うことを示し、次に、型をキャストするときにどのくらいのスペースを割り当てるかをコンパイラーに指示します。結局のところ、最後の例で ではなくinttype にキャストした場合、自由に使えるのは 16 ビットではなく 8 ビットだけになり、結果は違ったものになっていたでしょう。小数型 (および) の場合、縮小は異なる方法で行われます。このような数値を整数型に変換しようとすると、小数部分は切り捨てられます。 byteshortfloatdouble
public static void main(String[] args) {

   double d = 2.7;

   long x = (int) d;
   System.out.println(x);
}
コンソール出力: 2

データ型 char

char 型は個々の文字を表示するために使用されることはすでにご存知でしょう。
public static void main(String[] args) {

   char c = '!';
   char z = 'z';
   char i = '8';

}
ただし、理解することが重要な機能が多数あります。値の範囲を示す表をもう一度見てみましょう。
プリミティブ型 メモリ内のサイズ 値の範囲
バイト 8ビット -128~127
短い 16ビット -32768 ~ 32767
チャー 16ビット 0から65536まで
整数 32ビット -2147483648 から 2147483647
長さ 64ビット -9223372036854775808 から 9223372036854775807
浮く 32ビット (2の-149乗)から((2-2の-23乗)*2の127乗)
ダブル 64ビット (-2 の 63 乗) から ((2 の 63 乗)-1)
ブール値 8 (配列で使用する場合)、32 (配列以外で使用する場合) 正しいか間違っているか
この型のchar数値範囲は 0 ~ 65536 です。しかし、これは何を意味するのでしょうか? 結局のところ、charこれらは数字だけでなく、文字、句読点でもあります...事実、値はcharUnicode形式でJavaに保存されます。Unicode については、これまでの講義ですでに触れています。Unicode は、世界中のほぼすべての書き言葉の文字を含む文字エンコード標準であることを覚えているでしょう。言い換えれば、これは、あらゆる言語のほぼすべての文字のコードが含まれる特別なコードのリストです。一般的な Unicode テーブルは非常に大きいため、もちろん暗記する必要はありません。たとえば、ここにその一部を示します。 プリミティブ型の拡張と縮小 - 5 重要なことは、値を格納する原理を理解することですchar。また、特定のシンボルのコードを知っていれば、いつでもプログラム内でそれを取得できることを覚えておいてください。乱数を使ってこれを試してみましょう。
public static void main(String[] args) {

   int x = 32816;

   char c = (char) x ;
   System.out.println(c);
}
コンソール出力: 耰 これは、Java で文字が格納される形式ですchar。各文字は数値、つまり 16 ビット、つまり 2 バイトの数値コードに対応します。Unicode 32816 は文字「耰」に対応します。この瞬間に注目してください。この例では、変数 を使用しましたintこれは32 ビットのメモリを占有しますが、char16 ビットはメモリを占有します。ここでは、必要な数値 32816 が範囲外であるため、選択しました。short と同様に、size は16 ビットですが、範囲内に負の数値がないため、「正」の範囲は2 倍の大きさになります ( 32767 ではなく 65536 )。コードが 65536 の範囲内にある限り、 を使用できます。ただし、数値 を作成すると、16 ビットを超える量が必要になります。種類を絞り込む場合: intshortcharcharcharshortintint >65536
char c = (char) x;
余分なビットは破棄され、結果はまったく予期しないものになります。

文字と整数の加算の特徴

この珍しい例を見てみましょう。
public class Main {

   public static void main(String[] args) {

      char c = '1';

      int i = 1;

       System.out.println(i+c);
   }
}
コンソール出力: 50 O_O ロジックはどこですか? 1+1、50ってどこから来たの?! char値は、キャラクターの Unicode を表す 0 ~ 65536 の範囲の数値としてメモリに保存されること はすでにご存知でしょう。プリミティブ型の拡張と縮小 - 6 それで、ここにあります。加算を実行するとchar、ある整数型がcharUnicode で対応する数値に変換されます。コードで 1 と '1' を追加すると、シンボル '1' はコード 49 に変換されました (上の表で確認できます)。したがって、結果は 50 になりました。もう一度、古い友人である耰を例にして、これに何らかの数値を足してみましょう。
public static void main(String[] args) {

   char c = '耰';
   int x = 200;

   System.out.println(c + x);
}
コンソール出力: 33016これはコード 32816 に対応する ことがすでにわかっています。そして、この数値と 200 を加算すると、正確な結果が得られます - 33016 :) ご覧のとおり、操作のメカニズムは非常に単純です。
コメント
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION