説明に のサブクラスをもう 1 つ追加しました。
Tree
/ \
/ \
/ \
Redwood Blackwood
この階層では:
アップキャスト: クラス階層に沿ってある方向に参照をキャストするときfrom the sub classes towards the root
。この場合、キャスト演算子を使用する必要はありません
大文字の例:
ARedwood
またはBlackwood
両方tree
: そう
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = b; // Valid
ダウンキャスト: クラス階層に沿ってある方向に参照をキャストする場合from the root class towards the children or subclasses
。明示的に型キャストする必要があります。
ダウンキャストの例:
Redwood r = new Tree(); //compiler error, because Tree is not a Redwood
Blackwood r = new Tree(); //compiler error, because Tree is not a Blackwood
どちらかまたはオブジェクトTree object
を実際に指している場合は、 キャスト a を明示的に入力する必要があります。そうでない場合は、実行時にエラーになります。例えばRedwood
Blackwook
この場合:
Tree t1;
Tree t2;
Redwood r = new Redwood() ;
Blackwood b = new Blackwood() ;
t1 = r; // Valid
t2 = r; // Valid
Redwood r2 = (Redwood)t1;
Blackwood b2 = (Blackwood)t2
[答え]
Redwood r = (Redwood) new Tree();
なぜコンパイラエラーがないのですか?
Downcastの例:
ソースのRedwood r = (Redwood) new Tree();
最初に Tree オブジェクトを作成し、 に型キャストしRedwood
ます。
これは次のように考えることができます。
Tree t = new Tree();`
Redwood r = (Redwood)t;
したがって、コンパイル時には問題ありません。
[答え]
なぜランタイムエラー?
しかし、実際にはサブクラスはスーパークラスのオブジェクトRedwood
を指すことはできません。Tree
そのため、コードは実行時に失敗します。
ツリー t = 新しいツリー();
t
対象Tree()
外Redwood()
です。それが実行時エラーの理由です。
コンパイラは現在、値とは何かt
を構文的に記述していません。しかし、実行時にが故障した場合のオブジェクトはRedwood r = (Redwood)t;
whereです。 t
Tree class
[提案:]
instanceof演算子 を使用することをお勧めします。
キャスト/強制操作は型間の変換に使用され、instanceof演算子は実行時に型情報をチェックするために使用されます。
説明:
instanceof演算子を使用すると、オブジェクトの型を判別できます。演算子の左側にオブジェクト、演算子の右側に型を取り、オブジェクトがその型に属しているかどうかを示すブール値を返します。これは、次の例で最も明確に示されています。
if (t instanceof Redwood)
{
Redwood r = (Redwood)t;
// rest of your code
}
ただし、基本型から派生型へのキャストは悪いことです。
参考:instanceof演算子に注意