- PR -

キャストについて

投稿者投稿内容
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-03-30 20:03
キャストが失敗するときは、必ずgetClass()を使って確認してみてください。
コード:
Object[] obj = new Object[3];
System.out.println(obj.getClass());


この場合、
コード:
class [Ljava.lang.Object;


と表示されます。これは<java.lang.Objectの配列>というクラスです。
変数objには<java.lang.Objectの配列>のインスタンスが格納されています。
この<java.lang.Objectの配列>クラスは、スーパークラスがjava.lang.Objectです。
このコードでスーパークラスがjava.lang.Objectであると確認できます。
コード:
Object[] obj = new Object[3];
Class c = obj.getClass();
System.out.println(c.getSuperclass());



次に、
コード:
Object[] obj = new String[3];
System.out.println(obj.getClass());


この場合、
コード:
class [Ljava.lang.String;


と表示されます。これは<java.lang.Stringの配列>というクラスです。
変数objには<java.lang.Stringの配列>のインスタンスが格納されています。
この<java.lang.Stringの配列>クラスは、スーパークラスがjava.lang.Objectです。

つまり、両方ともjava.lang.Object型から派生したクラスであり、
お互いに互換性はありません。従ってキャストはできません。
OZ
常連さん
会議室デビュー日: 2006/02/27
投稿数: 45
投稿日時: 2006-03-30 21:32
引用:

かつのりさんの書き込み (2006-03-30 20:03) より:
キャストが失敗するときは、必ずgetClass()を使って確認してみてください。
コード:
Object[] obj = new Object[3];
System.out.println(obj.getClass());


この場合、
コード:
class [Ljava.lang.Object;


と表示されます。これは<java.lang.Objectの配列>というクラスです。
変数objには<java.lang.Objectの配列>のインスタンスが格納されています。
この<java.lang.Objectの配列>クラスは、スーパークラスがjava.lang.Objectです。
このコードでスーパークラスがjava.lang.Objectであると確認できます。
コード:
Object[] obj = new Object[3];
Class c = obj.getClass();
System.out.println(c.getSuperclass());



次に、
コード:
Object[] obj = new String[3];
System.out.println(obj.getClass());


この場合、
コード:
class [Ljava.lang.String;


と表示されます。これは<java.lang.Stringの配列>というクラスです。
変数objには<java.lang.Stringの配列>のインスタンスが格納されています。
この<java.lang.Stringの配列>クラスは、スーパークラスがjava.lang.Objectです。

つまり、両方ともjava.lang.Object型から派生したクラスであり、
お互いに互換性はありません。従ってキャストはできません。




かつのりさん、ありがとうございます。
確かにキャストできないケースでは、
コード:
class [Ljava.lang.Object;


と表示されます。

ただし、それはなぜという点になるとお恥ずかしいのですがまだ完全には理解できていません。
ここはインギさんの仰る通り、暫くは
引用:

建設的でないかもしれませんが、ひとまずは "Javaのクセ" 程度に考えてしまってはいかがでしょうか。


と思う事にします。

助言下さった皆様、ありがとうございました。
結果として完全に理解できるところまで行けませんでしたが、もう少しやりながらこのページを見直して理解できるようにしようと思います。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2006-03-31 01:12
「配列オブジェクトがキャスト可能か?」を考えるのに、
「配列要素がキャスト可能か?」を考慮するから話が複雑になるのです。

実際は、「あるオブジェクトがキャスト可能か?」を判定する際に考慮されるのは、
「そのオブジェクトのデータ型」だけです。
変数宣言がどの型になっているか、要素の宣言の型は何か、
要素が保持している値の実際の型は何か、といった条件は一切無関係です。

Object[] obj = new Object[3];
...
String[] s = (String[])obj;

とした場合に問題になるのは、
「キャストしようとしているオブジェクトの実際の型はObject[]である」
「Object[]は、String[]にキャストできない」
ということだけです。
objの要素が実際にはどんなデータ型なのかは斟酌されません。

みなさん、問題を複雑に考えすぎではないですか?
progman
大ベテラン
会議室デビュー日: 2005/06/08
投稿数: 227
投稿日時: 2006-03-31 09:14
StringはObjectを継承している。
String[]はObject[]を継承していない。

と考えたらスンナリしませんか?
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-03-31 09:26
引用:

coasmさんの書き込み (2006-03-31 01:12) より:
objの要素が実際にはどんなデータ型なのかは斟酌されません。
みなさん、問題を複雑に考えすぎではないですか?


質問者以外のどこのだれが?
質問者がかってにそっちの方向へ逝っただけに見えるんだが。
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-03-31 09:27
引用:

progmanさんの書き込み (2006-03-31 09:14) より:
StringはObjectを継承している。
String[]はObject[]を継承していない。

と考えたらスンナリしませんか?



しないと思う。
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2006-03-31 09:59
引用:

progmanさんの書き込み (2006-03-31 09:14) より:

String[]はObject[]を継承していない。


そうだったの!? Σ(@o@;

・・・んなわけないでしょ。
Objectクラスはすべてのクラスの基本クラスなんだし、
だいたい、Object[]にはString[]が代入できるでしょうが。

引用:

coasmさんの書き込み (2006-03-31 01:12) より:

objの要素が実際にはどんなデータ型なのかは斟酌されません。


スレ主以外の方は、みんなわかってらっしゃいますよ。
コンパイル時にはまったく問題はない。
しかし、実行時にキャストなどを伴う場合には、相応の対処が必要です。

それにしてもスレ主さん、腰が低くてまじめそうに見えますが、どの程度素直なのやら。
ご自身の先入観(オレ的オブジェクト理論)に固執して、
他の方の意見を選り好みしているように見えるのは、私の気のせいですか?
BBSの使い方は人それぞれですし、100%悪い、というものでもありませんが、
ここは「もったいない」と表現しておくにとどめましょう。

[ メッセージ編集済み 編集者: Edosson 編集日時 2006-03-31 10:00 ]
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-31 10:41
引用:

progmanさんの書き込み (2006-03-31 09:14) より:

StringはObjectを継承している。
String[]はObject[]を継承していない。

と考えたらスンナリしませんか?


これがスンナリ納得できる理由になりえるんでしょうか?
確かに Object[] は継承していないですが、Object (配列でない) は継承していますよね。

コード:

    /** コードにして確かめると多分こんな感じ */
    private static void makiMakiLove() {
        Object[] arrayString = new String[3];
        Class c1 = arrayString.getClass();

        // (出力結果も多分こんな感じ)
        System.out.println(c1.getName());                  // [Ljava.lang.String;
        System.out.println(c1.getSuperclass().getName());  // java.lang.Object
    }


progman さんの考えで納得するのであれば、"逆に" 次のことが言えなければならないと思います。

 String[] は Object (配列ではない) を 継承している "ので"
 Object (配列ではない) から String[] に無条件にキャストできる。

これは正しいのでしょうか?
正しくなければ、スンナリ納得できないと思います。

私が読み違いをしているのであればごめんなさい。
Java は 2 年前に 3 ヶ月程度しかやってないので言語仕様すらまともに知りませんw (*_ _)

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌

スキルアップ/キャリアアップ(JOB@IT)