web-dev-qa-db-ja.com

Javaの変数のキャスト

キャストがどのように機能するのか教えてもらえますか? whenするべきだと理解していますが、実際にはどのように機能するかはわかりません。プリミティブデータ型については部分的に理解していますが、オブジェクトをキャストすることになると、その仕組みがわかりません。

タイプObjectのオブジェクトを、MyType(単なる例)に突然キャストして、すべてのメソッドを取得するにはどうすればよいですか?

77
user626912

Javaでのキャストは魔法ではありません。それは、タイプAのオブジェクトは実際にはより具体的なタイプBであるとコンパイラーに伝えるため、Bのすべてのメソッドにアクセスできなかったことです。さもないと。キャストを実行するときに、魔法や変換を実行しているわけではなく、基本的にコンパイラーに「信頼してください。私がやっていることを知っています。この行のこのオブジェクトが実際に<Insert castここに入力>。」例えば:

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

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

なぜキャストが必要なのですか?まず、より一般的なタイプからより具体的なタイプに移行する場合にのみ必要です。たとえば、IntegerNumberを継承するため、IntegerNumberとして格納する場合は問題ありません(すべての整数は数値であるため)。ただし、逆方向に移動する場合は、すべての数値が必要ではありません整数(DoubleFloatByteLongなどの整数もあります)そして、プロジェクトまたはJDKにサブクラスが1つしかない場合でも、誰かが簡単に別のサブクラスを作成して配布できるので、単一の明らかな選択だと思います!

キャストの使用に関しては、いくつかのライブラリでそれが必要であることに変わりはありません。すべてのコレクションがオブジェクトの追加に取り組み、コレクションから戻った結果をキャストするので、Java 5より前では、コレクションおよびその他のさまざまなクラスで頻繁に使用されていました。ただし、ジェネリックの出現により、キャストの使用の多くはなくなりました-ClassCastExceptionsの可能性なしに、はるかに安全な代替を提供するジェネリックに置き換えられました(実際、ジェネリックをきれいに使用し、警告なしでコンパイルする場合、 ClassCastExceptionが発生しないことが保証されています。)

171
Michael Berry

実際、キャストは常に機能するとは限りません。オブジェクトがinstanceofでない場合、それをキャストしているクラスは実行時にClassCastExceptionを取得します。

7
sandrstar

StringFileにキャストしたい場合(はい、意味がありません)、Fileクラスは子ではなく、Stringクラスの親でもないので、直接キャストすることはできません(コンパイラーは文句を言います)。

ただし、StringObjectであるため(Stringは親)、ObjectObjectにキャストできます。 FileはFileであるため、このオブジェクトをObjectにキャストできます。

したがって、すべての操作はコンパイル時の入力の観点からは「合法」ですが、実行時に機能するという意味ではありません!

File f = (File)(Object) "Stupid cast";

コンパイラは、それが意味をなさない場合でもこれを許可しますが、この例外を使用して実行時にクラッシュします。

Exception in thread "main" Java.lang.ClassCastException:
    Java.lang.String cannot be cast to Java.io.File
5

参照のキャストは、そのタイプのinstanceofである場合にのみ機能します。ランダム参照をキャストすることはできません。また、 Casting Objects の詳細を読む必要があります

例えば.

String string = "String";

Object object = string; // Perfectly fine since String is an Object

String newString = (String)object; // This only works because the `reference` object is pointing to a valid String object.
2
asgs