「クラス」変数を​​instanceofに渡せないのはなぜですか?


89

このコードがコンパイルされないのはなぜですか?

    public boolean isOf(Class clazz, Object obj){
        if(obj instanceof clazz){
            return true;
        }else{
            return false;
        }
    }

クラス変数をに渡せないのはなぜinstanceofですか?

回答:


131

instanceofオペレータは、参照型で、のような作品Integerのように、ではなく、オブジェクトの上にnew Integer(213)。あなたはおそらく次のようなものが欲しいでしょう

clazz.isInstance(obj)

補足:あなたが書くとあなたのコードはより簡潔になります

public boolean isOf(Class clazz, Object obj){
    return clazz.isInstance(obj)
}

あなたがもう方法を必要とするかどうかは本当にわかりませんが。


コードがまったく役に立たないことはわかっています。混乱を示したいだけです:)
eric2323223 2010

6
IntegerクラスリテラルではありませんInteger.classクラスリテラルになります(JLSの§15.8.2を参照:java.sun.com/docs/books/jls/third_edition/html/…)。instanceof:演算子は、JLSの指定§15.20.2として(タイプ名別名)「のReferenceType」を取るjava.sun.com/docs/books/jls/third_edition/html/...
ヨアヒム・ザウアー

3
clazz.isInstance(obj)オブジェクトはすでに提供されているので使用します。
ドナーフェロー

13

instanceof明示的なクラス名(コンパイル時に指定)でのみ使用できます。行うためには、ランタイムチェックを、あなたが行う必要があります。

clazz.isInstance(obj)

これはclazz.isAssignableFrom(..)、ケースをobj == nullより適切に処理するため、わずかな利点があります。


5

他の人が述べたように、instanceofクラス変数はオブジェクトのインスタンスを参照するため、クラス変数を渡すことはできませんが、の右手instanceof型である必要があります。つまり、instanceof「yはオブジェクトxのインスタンスである」という意味ではなく、「yはタイプXのインスタンスである」という意味です。オブジェクトとタイプの違いがわからない場合は、次のことを考慮してください。

Object o = new Object();

ここで、タイプはObject、でoあり、そのタイプのオブジェクトのインスタンスへの参照です。したがって:

if(o instanceof Object)

有効ですが

if(o instanceof o)

o右側にタイプではなくオブジェクトがあるからではありません。

より具体的には、クラスインスタンスは型ではなく、オブジェクト(JVMによって作成されます)です。あなたのメソッドでClassは、は型clazzですが、オブジェクトです(まあ、オブジェクトへの参照)

必要なのは、オブジェクトをクラスオブジェクトと比較する方法です。これは人気があることがわかったので、これはクラスオブジェクトのメソッドとして提供されますisInstance()

isInstanceのJavaDocは、これをよりよく説明しています。

public boolean isInstance(Object obj)

指定されたオブジェクトが、このクラスによって表されるオブジェクトと割り当て互換であるかどうかを判別します。このメソッドは、Java言語のinstanceof演算子と動的に同等です。指定されたObject引数がnull以外の場合、メソッドはtrueを返し、ClassCastExceptionを発生させることなく、このClassオブジェクトによって表される参照型にキャストできます。それ以外の場合はfalseを返します。

具体的には、このClassオブジェクトが宣言されたクラスを表す場合、指定されたObject引数が表されたクラス(またはそのサブクラスのいずれかのインスタンス)である場合、このメソッドはtrueを返します。それ以外の場合はfalseを返します。このClassオブジェクトが配列クラスを表す場合、指定されたObject引数がID変換または拡張参照変換によって配列クラスのオブジェクトに変換できる場合、このメソッドはtrueを返します。それ以外の場合はfalseを返します。このClassオブジェクトがインターフェイスを表す場合、指定されたObject引数のクラスまたはスーパークラスがこのインターフェイスを実装していれば、このメソッドはtrueを返します。それ以外の場合はfalseを返します。このClassオブジェクトがプリミティブ型を表す場合、このメソッドはfalseを返します。

パラメータ: obj-チェックするオブジェクト
戻り値: objがこのクラスのインスタンスである場合はtrue
以降: JDK1.1


3

まず、instanceof右側のオペランドが実際のクラス(obj instanceof Objectまたはobj instanceof Integer)であり、型の変数ではないことを要求しますClass。第二に、あなたは本当にすべきではないかなり一般的な初心者の間違いを犯しました...次のパターン:

if(conditional_expression){
    trueを返します。
} そうしないと{
    falseを返します。
}

上記は次のようにリファクタリングできます。

戻り条件式;

冗長なif ... elseステートメントが削除されるため、常にそのリファクタリングを実行する必要があります。同様に、式は同じ結果にリファクタリング可能です。return conditional_expression ? true : false;


2
それは間違いではありません。不器用かもしれませんが、まったく問題ありません。予見可能な将来に戻る前に、追加のコードが必要な場合があります...
信じられないほどの
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.