- - PR -
親クラスと子クラス間の配列について
1
投稿者 | 投稿内容 | ||||||||
---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2004-10-10 15:36
皆さん始めまして、Java初心者のwlです。
親クラスと子クラス間の配列について皆さんにお聞きしたいのですが、 以下のクラスがあるときに、 class Super{} class Sub extends Super {} public class Sample { public static void main(String[] args) { Super[] sps = {new Sub(), new Sub()}; Sub[] sbs = (Sub[])sps; } 何故『Sub[] sbs = (Sub[])sps;』ではコンパイルエラーにはならないが、 実行エラーになるのでしょうか? Super[]とSub[]は何らかの形で関係を持っていますか? ご存知の方是非教えてください。 宜しくお願いします。 | ||||||||
|
投稿日時: 2004-10-10 15:54
wlさん、こんにちは。
Superと Subは super/subの関係であったとしても、 それらの配列 Super[]と Sub[]は各々別物で super/subの関係にありません。 配列はそれ自体がクラスであることを思い出してください。 (追加) それと、
って
としなくてもよかったでした? [ メッセージ編集済み 編集者: Kissinger 編集日時 2004-10-10 15:57 ] | ||||||||
|
投稿日時: 2004-10-10 16:56
Kissingerさん、こんにちは。
返事していただき、どうもありがとう御座いました。 >Superと Subは super/subの関係であったとしても、 >それらの配列 Super[]と Sub[]は各々別物で super/subの関係にありません。 >配列はそれ自体がクラスであることを思い出してください。 ⇒ご指摘の通りだと思います。 しかし、自分が理解できないところは、もし関係がない場合 何故コンパイルエラーにはならないというところです。 一般的に継承関係のないクラス同士をキャストしようとすると コンパイルエラーになりますが、述べた例では、コンパイルエラーではなく 実行時にエラーになります。 >Super[] sps = new Super[] {new Sub(), new Sub()}; >としなくてもよかったでした? ⇒しなくてもよいと思いますが、間違えっていたらご指摘願います。 宜しくお願いします。 | ||||||||
|
投稿日時: 2004-10-10 23:12
コンパイルエラーにならない理由ですが、それは java.lang.ClassCastException が非検査例外だからです。
詳しいことは言語仕様を参照していただきたいのですが、Super[] から Sub[] への変換は、要素型である Super から Sub への変換が参照型の縮小変換であるので、同様に参照型縮小変換になります。 この変換は実行時に検査されて、変換不可能な場合には ClassCastException が発生します。 コンパイルエラーになるケースですが、これは次のように一方が他方のサブクラスであるという関係にない場合に発生します。
かなり端折って書くと、変数としての型が合っていない場合はコンパイル時、変数の型は合っているがオブジェクトの型が合わない場合は実行時に検査されるということです。 | ||||||||
|
投稿日時: 2004-10-10 23:20
Kissinger さんへのフォローです。
配列宣言時に初期化もする場合は
で大丈夫ですね。 宣言だけして後で設定する場合は、ご指摘の通り
と書く必要があります。 | ||||||||
|
投稿日時: 2004-10-11 00:03
Gioさん、
初期化の件、ありがとうございました。 | ||||||||
|
投稿日時: 2004-10-11 13:46
Gioさん、非常に丁寧な説明どうもありがとう御座います。
確認ですが、 instanceofでfalseになるケースが実行エラーになり、 instanceofでコンパイルエラーになるケースがコンパイルエラーになる という認識で大丈夫ですか? [ メッセージ編集済み 編集者: wl 編集日時 2004-10-11 13:53 ] |
1