キャストのしくみを教えてもらえませんか?いつ行うべきかは理解していますが、実際にはどのように機能するかはわかりません。プリミティブデータ型については部分的に理解していますが、オブジェクトのキャストに関しては、それがどのように機能するかを理解していません。
Object型のオブジェクトを突然キャストしてMyType
(単なる例)、すべてのメソッドを取得するにはどうすればよいですか?
キャストのしくみを教えてもらえませんか?いつ行うべきかは理解していますが、実際にはどのように機能するかはわかりません。プリミティブデータ型については部分的に理解していますが、オブジェクトのキャストに関しては、それがどのように機能するかを理解していません。
Object型のオブジェクトを突然キャストしてMyType
(単なる例)、すべてのメソッドを取得するにはどうすればよいですか?
回答:
Javaでのキャストは魔法ではありません。コンパイラーに、タイプAのオブジェクトは実際にはより具体的なタイプBであると伝え、他の方法では得られなかったBのすべてのメソッドにアクセスできるようにします。キャストを実行するときに、魔法や変換を実行していません。基本的に、コンパイラに「信頼してください。私が何をしているのかを知っています。この行のこのオブジェクトが実際には<キャストを挿入することを保証できます。ここに入力>。」例えば:
Object o = "str";
String str = (String)o;
上記は問題ありませんが、魔法ではありません。oに格納されているオブジェクトは実際には文字列であるため、問題なく文字列にキャストできます。
これがうまくいかない可能性がある2つの方法があります。まず、完全に異なる継承階層の2つのタイプ間でキャストしている場合、コンパイラはあなたがばかげていることを認識し、あなたを止めます。
String o = "str";
Integer str = (Integer)o; //Compilation fails here
次に、それらが同じ階層にあるが、それでも無効なキャストである場合、ClassCastException
実行時にaがスローされます。
Number o = new Integer(5);
Double n = (Double)o; //ClassCastException thrown here
これは本質的に、コンパイラの信頼に違反したことを意味します。オブジェクトが特定のタイプであることを保証できるとおっしゃいましたが、そうではありません。
なぜキャストが必要なのですか?さて、最初に、より一般的なタイプからより具体的なタイプに移行するときにのみ必要です。たとえば、Integer
から継承するNumber
ので、をInteger
として保存する場合は問題ありませんNumber
(すべての整数が数値であるため)。ただし、逆に移動する場合はキャストが必要です。すべての数値が整数であるとは限りません(同様に)我々が持っている整数としてDouble
、Float
、Byte
、Long
、など)をプロジェクトまたはJDKでただ一つのサブクラスがありますとしても、誰かが簡単にあなたが保証をしたんので、あなたはそれが単一、当然の選択だと思う場合でも、別のものを作成して、それを配布することができ!!
キャストの使用に関しては、一部のライブラリでまだその必要性が見られます。Java-5より前は、すべてのコレクションがオブジェクトの追加と、コレクションから取得した結果のキャストに取り組んでいたため、コレクションやその他のさまざまなクラスで頻繁に使用されていました。ただし、ジェネリックの出現により、キャストの使用の多くはなくなりました-ClassCastExceptionsの可能性なしに、はるかに安全な代替手段を提供するジェネリックに置き換えられました(実際、ジェネリックをクリーンに使用し、警告なしでコンパイルする場合、 ClassCastExceptionが発生しないことが保証されています。)
Double.valueOf(gpsLastLoc.getLatitude()).getClass().getSimpleName()
。どちらの場合も、プリミティブのクラスを動的に取得する必要はありません。doubleプリミティブをgetLatitude()
返す場合は、Double
オブジェクトにプロモートすることが常にわかっているからです。
aString
をaにキャストしたいとしますFile
(はい、意味がありません)。File
クラスはクラスの子でも親でもないため、直接キャストすることはできませんString
(コンパイラが文句を言います)。
しかし、あなたはあなたを唱えられるString
にObject
あるため、String
あるObject
(Object
親です)。次に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.