- ゴングラッチェ
- 常連さん
- 会議室デビュー日: 2006/03/03
- 投稿数: 36
|
投稿日時: 2006-03-30 16:54
引用: |
| どうやら、箱(変数宣言)と中身(インスタンス生成)以外にも、配列そのものと配列の中身を同一視しているらしい・・・
|
ぶざいくろうさんの指摘は当たってそうですね。
OZさんは「配列の中身がStringならば、その配列はStringの配列である。」と思っているのではないでしょうか。これが違います。正しくは「Objectの配列の中身にStringが入っているだけで、配列はObjectの配列である。」となります。配列の型は中身によって変わることはありません。
混乱の基かもしれませんが、ここで理解の糸口になりそうな問題をだしてみます。『Javaの配列は、配列そのものがインスタンスとして存在します。』さて、Object配列のインスタンスをString配列にダウンキャストできるでしょうか?
ヒント:ObjectのインスタンスをStringにダウンキャストできないのは実験済みですね。
|
- OZ
- 常連さん
- 会議室デビュー日: 2006/02/27
- 投稿数: 45
|
投稿日時: 2006-03-30 17:31
皆様、ながながとありがとうございます。
引用: |
|
Edossonさんの書き込み (2006-03-30 16:36) より:
さて性懲りもなく(^ ^;
引用: |
|
OZさんの書き込み (2006-03-30 15:33) より:
obj instanceof String[])はtrueとなっていますし。
|
本当に?
|
すみません、激しくうそをついていました。falseです・・・。
(obj[n] instanceof String)と勘違いしていました
引用: |
|
というわけで、こういうのは自分で叩いて身につけるのが、一番速いですよ。
コード: |
|
Object[] obj = null;
String[] str = null;
obj = new String[3];
obj[0] = new String();
obj[1] = new String();
obj[2] = new String();
System.out.println("obj is instance of String[] : " + (obj instanceof String[]));
str = (String[])obj;// <-- さて、ここではClassCastExceptionは発生する?
obj = new Object[3];
obj[0] = new String();
obj[1] = new String();
obj[2] = new String();
System.out.println("obj is instance of String[] : " + (obj instanceof String[]));
str = (String[])obj;
|
今回は、実際に走らせてみました。m(_ _)m
|
指摘された場所ではClassCastExceptionは発生せず、一番最後で発生しました。
引用: |
|
ゴングラッチェさんの書き込み (2006-03-30 16:54) より:
引用: |
| どうやら、箱(変数宣言)と中身(インスタンス生成)以外にも、配列そのものと配列の中身を同一視しているらしい・・・
|
ぶざいくろうさんの指摘は当たってそうですね。
OZさんは「配列の中身がStringならば、その配列はStringの配列である。」と思っているのではないでしょうか。これが違います。正しくは「Objectの配列の中身にStringが入っているだけで、配列はObjectの配列である。」となります。配列の型は中身によって変わることはありません。
|
これは、配列の場合だけでしょうか?
引用: |
|
正しくは「Objectの配列の中身にStringが入っているだけで、配列はObjectの配列である。」となります。配列の型は中身によって変わることはありません。
|
が理由でキャストできないのであれば、
引用: |
|
コード: |
|
1 : Object obj = new String();
2 : Object obj2 = new Object();
3 : obj = new String("文字1");
4 : obj2 = new String("文字2");
5 : String str = (String)obj;
6 : String str2 = (String)obj2;
|
4の時点でobj2はStringになってるだろ。(格納してる方じゃなく実体の方)
つまり、Object obj2 = new String("文字2");と結果同じなんだよ。
|
の場合も、5,6でエラーになるはずでは???
何か根本的に勘違いしているでしょうか・・・。
引用: |
|
混乱の基かもしれませんが、ここで理解の糸口になりそうな問題をだしてみます。『Javaの配列は、配列そのものがインスタンスとして存在します。』さて、Object配列のインスタンスをString配列にダウンキャストできるでしょうか?
ヒント:ObjectのインスタンスをStringにダウンキャストできないのは実験済みですね。
|
ひょっとして、「できない」でしょうか?
■配列ではない場合
コード: |
|
1 : Object obj = new Object();
2 : obj = new String("hoge");
|
1:当然、Object型
2:ここでインスタンスはString型に変更
よって、キャスト可能。
■配列の場合
コード: |
|
1 : Object[] obj = new Object[3];
2 :
3 : obj[0] = new String("hoge1");
4 : obj[1] = new String("hoge2");
5 : obj[2] = new String("hoge3");
|
1のイメージ
obj<------------------ Object[]型
|---obj[0]<---------- Object型
|---obj[1]<---------- Object型
|---obj[2]<---------- Object型
3,4,5のイメージ
obj<------------------ Object[]型
|---obj[0]<---------- String型
|---obj[1]<---------- String型
|---obj[2]<---------- String型
従って、個々の要素はインスタンスがString型に変わっているからキャスト可能だけど
配列自体はObject[]型のままなのでString[]からObject[]へのキャストはできないという事でしょうか?
|
- じゃんぬねっと
- ぬし
- 会議室デビュー日: 2004/12/22
- 投稿数: 7811
- お住まい・勤務地: 愛知県名古屋市
|
投稿日時: 2006-03-30 18:02
あれ? 何か長引いてますね。
引用: |
|
OZさんの書き込み (2006-03-30 17:31) より:
従って、個々の要素はインスタンスがString型に変わっているからキャスト可能だけど
配列自体はObject[]型のままなのでString[]からObject[]へのキャストはできないという事でしょうか?
|
「配列自体」というと、どちらなのかわかりませんよね。
入れ物は Object[] でも問題ないですから。
配列の実際のインスタンスの型などと表現すれば良いのかな。
(配列の中身と書くと要素になるので)
_________________ C# と VB.NET の入門サイト
じゃんぬねっと日誌
|
- Edosson
- ぬし
- 会議室デビュー日: 2004/04/30
- 投稿数: 675
|
投稿日時: 2006-03-30 18:15
引用: |
|
OZさんの書き込み (2006-03-30 17:31) より:
指摘された場所ではClassCastExceptionは発生せず、一番最後で発生しました。
|
感想はそれだけですか?
自分でいうのもなんですが。
引用: |
|
引用: |
|
ゴングラッチェさんの書き込み (2006-03-30 16:54) より:
ぶざいくろうさんの指摘は当たってそうですね。
OZさんは「配列の中身がStringならば、その配列はStringの配列である。」と思っているのではないでしょうか。これが違います。正しくは「Objectの配列の中身にStringが入っているだけで、配列はObjectの配列である。」となります。配列の型は中身によって変わることはありません。
|
これは、配列の場合だけでしょうか?
|
参照型の変数はすべてです。
引用: |
|
引用: |
|
正しくは「Objectの配列の中身にStringが入っているだけで、配列はObjectの配列である。」となります。配列の型は中身によって変わることはありません。
|
が理由でキャストできないのであれば、
引用: |
|
コード: |
|
1 : Object obj = new String();
2 : Object obj2 = new Object();
3 : obj = new String("文字1");
4 : obj2 = new String("文字2");
5 : String str = (String)obj;
6 : String str2 = (String)obj2;
|
4の時点でobj2はStringになってるだろ。(格納してる方じゃなく実体の方)
つまり、Object obj2 = new String("文字2");と結果同じなんだよ。
|
の場合も、5,6でエラーになるはずでは???
何か根本的に勘違いしているでしょうか・・・。
|
すでに他の方が指摘してますが、3,4で、参照変数を両方とも、
Stringインスタンスへの参照に、上書きしてます。
1,2で代入した参照先なんか、吹っ飛んでますよ。
引用: |
|
引用: |
|
混乱の基かもしれませんが、ここで理解の糸口になりそうな問題をだしてみます。『Javaの配列は、配列そのものがインスタンスとして存在します。』さて、Object配列のインスタンスをString配列にダウンキャストできるでしょうか?
ヒント:ObjectのインスタンスをStringにダウンキャストできないのは実験済みですね。
|
ひょっとして、「できない」でしょうか?
|
私の先ほどのサンプルそのものです。
引用: |
|
■配列ではない場合
コード: |
|
1 : Object obj = new Object();
2 : obj = new String("hoge");
|
1:当然、Object型
2:ここでインスタンスはString型に変更
よって、キャスト可能。
|
何で「変更」なんて表現しているのかが不明。
この辺が、鍵かもしれません。
「犬」は「動物」ですが、「動物」と呼んだところで、「動物」そのものに変化するわけではありません。
「動物」として取り扱うのに、なんの支障もない、というだけで、「犬」には変わりない。
だから、ダウンキャストもできるわけで。
考えることは、1度にひとつだけにしましょう。
|
- OZ
- 常連さん
- 会議室デビュー日: 2006/02/27
- 投稿数: 45
|
投稿日時: 2006-03-30 18:46
皆様、ご丁寧にありがとうございます。
引用: |
|
引用: |
|
■配列ではない場合
コード: |
|
1 : Object obj = new Object();
2 : obj = new String("hoge");
|
1:当然、Object型
2:ここでインスタンスはString型に変更
よって、キャスト可能。
|
何で「変更」なんて表現しているのかが不明。
この辺が、鍵かもしれません。
|
申し訳ございません。正確な言い回しができていませんで。
1:Object型の参照変数にObject型のインスタンスへの参照が設定される
2:参照変数の型はObject型のままだが、参照先はnewされたString型へ変更
という言い方であっているでしょうか?
配列ではない場合は理解できていると思います。(・・・多分)
皆様の説明を読んでいるうちに、自分では
引用: |
|
どうやら、箱(変数宣言)と中身(インスタンス生成)以外にも、配列そのものと配列の中身を同一視しているらしい・・・
OZさんは「配列の中身がStringならば、その配列はStringの配列である。」と思っているのではないでしょうか。これが違います。正しくは「Objectの配列の中身にStringが入っているだけで、配列はObjectの配列である。」となります。配列の型は中身によって変わることはありません。
|
が、やはり理解できていないように思います。
これですと、
コード: |
|
Object obj = new Object();
obj = String("hoge");
|
も、「Object変数の中身が、ObjectインスタンスからStringインスタンスへ参照先が変わっただけで変数はObjectのままだからキャストはできない」と受け取れるのですが、これは間違いというのは実証済みですよね。
とすると、違いは「配列か、配列ではないか」に行き着いてしまうのですが。
|
- ぶさいくろう
- ぬし
- 会議室デビュー日: 2005/11/22
- 投稿数: 1232
- お住まい・勤務地: 川崎市(は俺も含めてロクな人間が住んでないよw)
|
投稿日時: 2006-03-30 18:53
すまねぇ、みんな。
オラ、なんか頭痛くなってきたぞ・・・orz
|
- OZ
- 常連さん
- 会議室デビュー日: 2006/02/27
- 投稿数: 45
|
投稿日時: 2006-03-30 19:01
引用: |
|
ぶさいくろうさんの書き込み (2006-03-30 18:53) より:
すまねぇ、みんな。
オラ、なんか頭痛くなってきたぞ・・・orz
|
申し訳ございません!!
|
- 山本 裕介
- ぬし
- 会議室デビュー日: 2003/05/22
- 投稿数: 2415
- お住まい・勤務地: 恵比寿
|
投稿日時: 2006-03-30 19:44
型については、やや極端に言えばどうすればコンパイルが通るようになるか、というコツを知っていれば不自由することはありません。
#例外処理についてはとりあえずコンパイルが通ればいい、って考え方は危険かもしれません
建設的でないかもしれませんが、ひとまずは "Javaのクセ" 程度に考えてしまってはいかがでしょうか。
言語によっては OZ さんの考えるとおりのコーディングで実行できる種類のもあります。(よね?)
当面はコンパイルが通って、ClassCastException が発生しない「感覚」をつかめればいいと思います。
コーディングを重ねるうちに自ずと仕組みがわかってくるかと。
それなりにJava のプログラミング経験がある人でも、String[] strArray = (String[])objArray; なんて表記はしょっちゅうしてしまうのではないでしょうか。
でも、間違いはコンパイラやIDEが即座に指摘してくれます。
「正しくはどう書くべきか」というルールは知っておく必要がありますが。
文法や言語のルールについてはコンパイラに考えて貰って、我々はアルゴリズムや設計にフォーカスすることをオススメします。
もちろん探求するのも大事なことですので、「このままではなんだか気が済まない!」という気分であればがんばってください!
[ メッセージ編集済み 編集者: インギ 編集日時 2006-03-30 19:46 ]
|