1. ホーム
  2. java

[解決済み] Javaでの変数のキャスティング

2023-06-02 04:30:16

質問

キャスティングの仕組みについて教えてください。私は とき というのはわかるのですが、それがどのように動作するのかはよくわかりません。プリミティブなデータ型については部分的に理解していますが、オブジェクトのキャストに関しては、どのように機能するのか理解していません。

Object 型のオブジェクトを突然、例えば、次のようにキャストすることができます。 MyType (単なる例です) にキャストして、すべてのメソッドを取得できるのでしょうか?

どのように解決するのですか?

Javaでのキャスティングは魔法ではありません。コンパイラに、A型のオブジェクトは実際にはもっと特殊なB型であると伝え、そうでなければ得られなかったBのすべてのメソッドにアクセスできるようにするものです。キャスティングの実行時に何らかのマジックや変換を行っているわけではなく、本質的にコンパイラに「私を信じてください、私は何をしているか分かっています、この行のこのオブジェクトは実際には <Insert cast type here> であることを保証します」と伝えていることになります。

Object o = "str";
String str = (String)o;

上記はマジックではなく、すべてうまくいっています。oに格納されているオブジェクトは実際には文字列なので、問題なく文字列にキャストすることができます。

これが間違っている可能性があるのは2つあります。まず、まったく異なる継承階層にある2つの型間でキャストしている場合、コンパイラはその愚かさを知って停止します。

String o = "str";
Integer str = (Integer)o; //Compilation fails here

次に、同じ階層にあるのに無効なキャストである場合は ClassCastException が実行時に投げられます。

Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here

これは本質的に、あなたがコンパイラの信頼に背いたことを意味します。オブジェクトが特定の型であることを保証すると言っておきながら、そうでなかったということです。

なぜキャスティングが必要なのでしょうか?まず最初に、より一般的な型からより特殊な型に移行する場合にのみ必要です。たとえば Integer から継承される Number を継承しているので、もし Integer として Number として使うのであれば、それは問題ありません(すべてのIntegerはNumbersですから)。しかし、その逆にしたい場合はキャストが必要です。 Double , Float , Byte , Long など)また、プロジェクトやJDKに1つのサブクラスがあったとしても、誰かが簡単に別のサブクラスを作成し、それを配布することができるので、1つの明白な選択だと思っていても保証はないのです

キャスティングの使用については、いくつかのライブラリでまだその必要性を見ています。すべてのコレクションはオブジェクトを追加し、その結果をコレクションにキャストして戻していたので、Java-5以前はコレクションやその他のさまざまなクラスで多用されていました。しかし、ジェネリックの出現により、キャスティングの用途の多くはなくなりました。ジェネリックが、ClassCastExceptionの可能性のない、より安全な代替手段を提供することに置き換わりました(実際、ジェネリックをきれいに使い、警告なしでコンパイルすれば、ClassCastExceptionが発生しないことが保証されています)。