キャストがどのように機能するのか教えてもらえますか? whenするべきだと理解していますが、実際にはどのように機能するかはわかりません。プリミティブデータ型については部分的に理解していますが、オブジェクトをキャストすることになると、その仕組みがわかりません。
タイプObjectのオブジェクトを、MyType
(単なる例)に突然キャストして、すべてのメソッドを取得するにはどうすればよいですか?
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
これは本質的に、コンパイラの信頼に違反したことを意味します。オブジェクトが特定のタイプであることを保証できると言ったが、そうではない。
なぜキャストが必要なのですか?まず、より一般的なタイプからより具体的なタイプに移行する場合にのみ必要です。たとえば、Integer
はNumber
を継承するため、Integer
をNumber
として格納する場合は問題ありません(すべての整数は数値であるため)。ただし、逆方向に移動する場合は、すべての数値が必要ではありません整数(Double
、Float
、Byte
、Long
などの整数もあります)そして、プロジェクトまたはJDKにサブクラスが1つしかない場合でも、誰かが簡単に別のサブクラスを作成して配布できるので、単一の明らかな選択だと思います!
キャストの使用に関しては、いくつかのライブラリでそれが必要であることに変わりはありません。すべてのコレクションがオブジェクトの追加に取り組み、コレクションから戻った結果をキャストするので、Java 5より前では、コレクションおよびその他のさまざまなクラスで頻繁に使用されていました。ただし、ジェネリックの出現により、キャストの使用の多くはなくなりました-ClassCastExceptionsの可能性なしに、はるかに安全な代替を提供するジェネリックに置き換えられました(実際、ジェネリックをきれいに使用し、警告なしでコンパイルする場合、 ClassCastExceptionが発生しないことが保証されています。)
実際、キャストは常に機能するとは限りません。オブジェクトがinstanceof
でない場合、それをキャストしているクラスは実行時にClassCastException
を取得します。
String
をFile
にキャストしたい場合(はい、意味がありません)、File
クラスは子ではなく、String
クラスの親でもないので、直接キャストすることはできません(コンパイラーは文句を言います)。
ただし、String
はObject
であるため(String
は親)、Object
をObject
にキャストできます。 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
参照のキャストは、そのタイプの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.