web-dev-qa-db-ja.com

「Class」変数をinstanceofに渡すことができないのはなぜですか?

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

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

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

78
eric2323223

instanceof演算子は、Integerなどの参照型では機能しますが、new Integer(213)などのオブジェクトでは機能しません。あなたはおそらく次のようなものが欲しい

clazz.isInstance(obj)

サイドノート:コードを書くと、より簡潔になります

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

メソッドがもう必要かどうかは確かではありませんが。

121
Robert Munteanu

instanceofは、明示的なクラス名(コンパイル時に示される)でのみ使用できます。 runtimeチェックを行うには、次を実行する必要があります。

_clazz.isInstance(obj)
_

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

12
Eyal Schneider

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

 if( 条件式 ){
 return true; 
} else {
 return false; 
} 

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

戻る 条件式; 

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

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

Object o = new Object();

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

if(o instanceof Object)

有効ですが

if(o instanceof o)

右側のoが型ではなくオブジェクトであるためではありません。

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

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

IsInstanceのJava Docを参照してください。

public boolean isInstance(Object obj)

指定されたオブジェクトが、このクラスによって表されるオブジェクトと割り当て互換性があるかどうかを判断します。このメソッドは、Java language instanceof演算子。それ以外の場合はfalseを返します。

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

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

3
Rick Hanlon II