- PR -

キャストについて

投稿者投稿内容
OZ
常連さん
会議室デビュー日: 2006/02/27
投稿数: 45
投稿日時: 2006-03-29 18:58
ObjectからStringへのキャストで、

Object[] obj = new Object[3];
obj[0] = new String("文字列1");
obj[1] = new String("文字列2");
obj[2] = null;

String s1 = (String)obj[0];
String s2 = (String)obj[1];
String s3 = (String)obj[2];
だと上手く行くのですが、
String[] str = (String[])obj; <---実際にやりたい処理
ですとClassCastExceptionとなってしまいます。
元のObject変数には、Stringとして代入しているので上手く行くと思ったのですが。
ちなみにそう思った根拠は下記のURLを参考にしました。
http://www.javaroad.jp/bbs/answer.jsp?q_id=20050513145513872

初歩的な問題かもしれませんが、こういった処理はできないのでしょうか?
できるとしたら何が原因なのかご教授下さい。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-03-29 19:47
理由を考える例。

コード:

    Object[] obj = new String[3];
    obj[0] = new String("文字列 1");
    obj[1] = new String("文字列 2");
    obj[2] = new String("文字列 3");

    String[] str = (String[])obj; // <---実際にやりたい処理


ダウンキャスト・Clone コピーしているわけではない・メモリ領域の位置は変わらない・元の型との互換

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
OZ
常連さん
会議室デビュー日: 2006/02/27
投稿数: 45
投稿日時: 2006-03-29 20:41
じゃんぬねっとさん、ありがとうございます。

主にここを参考にしながら調べてみました。
http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000107.html

あまり良くない事をやろうとしている事が分かりました。
しかし、理由は分かりませんでした。
私が思っていたのは、

=============================================
Object[] obj = new Object[3];   //<--(1).Object型の参照変数作成
obj[0] = new String("文字列1"); //<--(2).(1)の変数にString型インスタンスの参照を設定
obj[1] = new String("文字列2");
obj[2] = null;

String s1 = (String)obj[0];    //<--(3).obj[0]はObject型だが中身はString型インスタンスへの参照だから、
String s2 = (String)obj[1];    //    String型へダウンキャスト可能
String s3 = (String)obj[2];
//(obj[1],obj[2]についても同様)
=============================================

というものでした。
従って、配列を要素毎に行うのも一気に行うのも同じと思っていたのですが、
(1)を
=============================================
Object[] obj = new String[3];
=============================================
に変更すると上手く行くという事は、実際には(2)でString型のインスタンスが
作成されている訳ではないのでしょうか?
少し混乱しています。

かしん
常連さん
会議室デビュー日: 2004/08/27
投稿数: 25
お住まい・勤務地: 窓際
投稿日時: 2006-03-29 21:17
自分でも混乱しがちですが、配列も変数ですので、
コード:
Object[] obj = new String[3]; //String配列の変数
Object[] obj2 = new Object[3]; //Object配列の変数

String[] str = (String[])obj; //OK
String[] str2 = (String[])obj2; //NG



配列でない変数と同じ考えかたでよいはずです。
コード:
Object obj = new String(); //Stringの変数
Object obj2 = new Object(); //Objectの変数

String str = (String)obj; //OK
String str2 = (String)obj2; //NG



Object変数はString変数にできない。
Object配列変数はString配列変数にできない。
OZ
常連さん
会議室デビュー日: 2006/02/27
投稿数: 45
投稿日時: 2006-03-30 14:25
かしんさん、ありがとうございます。

引用:

配列でない変数と同じ考えかたでよいはずです。
コード:
Object obj = new String(); //Stringの変数
Object obj2 = new Object(); //Objectの変数

String str = (String)obj; //OK
String str2 = (String)obj2; //NG



Object変数はString変数にできない。
Object配列変数はString配列変数にできない。


これで分かったように思えたのですが、以下のテストを行ってまた分からなくなりました。

=============================================
Object obj = new String(); //<--(1)
Object obj2 = new Object(); //<--(2)

obj = new String("文字1"); //<--(3)
obj2 = new String("文字2"); //<--(4)

String str = (String)obj; //<--(5)
String str2 = (String)obj2; //<--(6)
=============================================

何故か今度は、(6)もOKとなります。
(2)でObject型インスタンス用の参照変数を作成しているのに、(4)でString型用の
参照変数に変わってしまったという事でしょうか?
このテストを踏まえて以下のテストをしてみました。

=============================================
Object[] obj = new Object[3]; //<--(1)

obj[0] = new String("文字1"); //<--(2)
obj[1] = new String("文字2"); //<--(3)
obj[2] = null; //<--(4)

String[] str = new String[3]; //<--(5)

str[0] = (String)obj[0]; //<--(6)
str[1] = (String)obj[1]; //<--(7)
str[2] = (String)obj[2]; //<--(

String[] str2 = (String)obj; //<--(9)
=============================================

(6)(7)(はOKなのに(9)ではやはりClassCastExceptionとなります。

何が違うのでしょうか?
ぶさいくろう
ぬし
会議室デビュー日: 2005/11/22
投稿数: 1232
お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
投稿日時: 2006-03-30 14:34
引用:
これで分かったように思えたのですが、以下のテストを行ってまた分からなくなりました。
Object obj = new String(); //<--(1)
Object obj2 = new Object(); //<--(2)
obj = new String("文字1"); //<--(3)
obj2 = new String("文字2"); //<--(4)
String str = (String)obj; //<--(5)
String str2 = (String)obj2; //<--(6)
何故か今度は、(6)もOKとなります。


4の時点でobj2はStringになってるだろ。(格納してる方じゃなく実体の方)
つまり、Object obj2 = new String("文字2");と結果同じなんだよ。

新たなインスタンスを参照するように変えてるんだからさ。
最初のじゃんぬねっと氏のヒントがまったく無駄になってるな。
引用:
Object[] obj = new Object[3]; //<--(1)
obj[0] = new String("文字1"); //<--(2)
obj[1] = new String("文字2"); //<--(3)
obj[2] = null; //<--(4)
String[] str = new String[3]; //<--(5)
str[0] = (String)obj[0]; //<--(6)
str[1] = (String)obj[1]; //<--(7)
str[2] = (String)obj[2]; //<--(8)
String[] str2 = (String)obj; //<--(9)
(6)(7)(8)はOKなのに(9)ではやはりClassCastExceptionとなります。


こっちは当初の投稿となんら変わりないので『なぜか9ではこうなります』といわれてもね・・・

[ メッセージ編集済み 編集者: ぶさいくろう 編集日時 2006-03-30 14:38 ]
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2006-03-30 14:49
箱(変数宣言)と中身(インスタンス生成)をごっちゃにしてるんですね。
1回、分けて書いてみてはどうですか。
引用:

Object obj = null;
Object obj2 = null;

Sgring str = null;
String str2 = null;

Object temp0 = new String();
Object temp1 = new Object();
String temp2 = new String("文字1");
String temp3 = new String("文字2");

obj = temp0; //<--(1)
obj2 = temp1; //<--(2)

obj = temp2; //<--(3)
obj2 = temp3; //<--(4)

str = (String)obj; //<--(5)
str2 = (String)obj2; //<--(6)

// おまけ:ただし、こちらは失敗する。
str = obj; //<--(5')
str2 = obj2; //<--(6')

Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2006-03-30 14:58
もうひとつ行きましょうか。
以下のコードは9行目でClassCastExceptionが発生します。
その理由を考えてみてください。
コード:
1 : String temp = new String();
2 : 
3 : String hoge1 = null;
4 : Object hoge2 = null;
5 : String hoge3 = null;
6 : 
7 : hoge1 = temp;
8 : hoge2 = hoge1;
9 : hoge3 = hoge2;

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