2009-11-12 13 views
5

Javaでのこれらの2つのキャスト方法の違いは何ですか? CastingClass.class.cast(objectToCast);Javaでこれらの2つのキャスト方法の違いは何ですか?

  1. (CastingClass) objectToCast;

  2. 次のようにClass#cast(Object)のソースは次のとおりです。

    public T cast(Object obj) { 
    if (obj != null && !isInstance(obj)) 
        throw new ClassCastException(); 
    return (T) obj; 
    } 
    

    ので、castは、キャスト操作の汎用ラッパーは基本的にですが、私はまだしていないなぜあなたはそれのための方法が必要であるか理解する。

+0

OK、私はちょうどあなたがプリミティブ型のラッパーにキャストする 'cast'を使用することができることに気づきました。例えば。 'Integer i = int.class.cast(" 1234 ");' –

+0

@simmbot:あなたはこれを_write_することができますが、あなたが考えると思われることはしません。それを試してみてください。 –

+0

これは、StringがInteger型ではないため、ClassCastExceptionをスローします。その場合、 'Integer.valueOf(" 1234 ")'が必要になります。 –

答えて

7

静的にリンクされたクラスに対してのみ、最初のフォームを使用できます。

多くの場合、十分ではありません。たとえば、リフレクションを使用してクラスインスタンスを取得した場合や、パラメータとしてメソッドに渡した場合などです。したがって第2の形式。

+0

最初の形式では、ソースコード内でキャストをベイク処理しています。再コンパイルせずに変更することはできません。 2番目の形式を使用すると、任意のクラスにキャストしようとすることができます。 –

4

(T)objectToCastと書くことができるので、Tがジェネリック型パラメータ(型消去のため)である場合。 Javaコンパイラはそれを可能にしますが、TObjectとして扱われます。したがって、キャストしているオブジェクトが実際にTのインスタンスでなくても、キャストは常に成功します。

+0

こんにちはパベル、もう少し説明してもらえますか? 'cast'はそれを行うように見えます:' return(T)obj; ' –

+0

あなたはそれを最も確実に書くことができます。単にコンパイラの警告を出すだけです。 – meriton

+0

@meriton:良い点、編集済み。私が言いたいのは、キャストはまだそれが本当にやるべきことをしないということです。 –

2

これは最初の普通のキャストです。キャストする型がコンパイル時に分かっていることが必要です。コンパイル時に、キャストであることを確認し、実行時にキャストであることをキャストするタイプが汎用でないかどうかをチェックします。

2つめはリフレクションAPIを使用します。キャストするクラスは実行時に知られている必要があります。コンパイル時には何も確認しませんが、実行時に常にキャストが正しいかどうかをチェックします。

タイプパラメータはコンパイルタイプでしか認識されないため、タイプパラメータ(式T.classはコンパイルされません)では2番目のアプローチを使用できません。

(Class.forName(String)などの)動的にロードされるクラスは、実行時にのみ認識されるため、最初のアプローチは使用できません。

編集:ただし、Pavelが指摘するように、動的にロードされるクラスにキャストすることは意味がありません。 Class.cast(Object)の唯一の本当の有用性は、あなたがクラスオブジェクトを利用できるようにした型パラメータにキャストすることです。

キャストする型に型パラメータが含まれていない場合、追加のコンパイル時のチェックでバグが検出され、実行時に型の安全性が失われ、起動する構文が短くなるため、

+2

しかし、動的にロードされるクラスの場合、なぜキャストが必要なのでしょうか?キャストは、通常、式に何らかの型を強制しますが、動的にロードされるクラスの場合は、型を事前に知る必要はありません。結局のところ、動的にロードされるクラスを持っている場合、 ' .cast()'の呼び出しで 'T 'が何であるのかわからないので、生のバージョンを使用するだけで、戻り値の型は'Object'であること - 多くのキャストはありません。それは型をチェックしますが、確かに 'Class.isInstance()'は同じことをする良い方法です。全体として、これは実際にはジェネリック専用であると私には思われます。 –

+0

あなたは正しいです。それに応じて私の答えを編集しました。 – meriton

0

HereClass#cast()という使用例があります。それは新しい洞察を与えるかもしれない。

1

には、キャストクラスをハードコードするためのがあります。

秒1で
(ClassToCast) objectToCast; 

鋳造クラス多分パラメータ:

Class toCast = getClassToCast(); 

toCast.cast(objectToCast); 
関連する問題