Java 为什么不能将“类”变量传递给 instanceof?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2590640/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 09:33:49  来源:igfitidea点击:

Why can't a "Class" variable be passed to instanceof?

javaclassinstanceof

提问by eric2323223

Why doesn't this code compile?

为什么这段代码不能编译?

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

Why I can't pass a class variable to instanceof?

为什么我不能将类变量传递给instanceof

采纳答案by Robert Munteanu

The instanceofoperator works on reference types, like Integer, and not on objects, like new Integer(213). You probably want something like

instanceof运算符适用于引用类型,如Integer,而不适用于对象,如new Integer(213)。你可能想要类似的东西

clazz.isInstance(obj)


Side note: your code will be more concise if you write

旁注:如果你写,你的代码会更简洁

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

Not really sure if you need a method anymore ,though.

不过,不太确定您是否还需要一种方法。

回答by Eyal Schneider

instanceofcan be used only with explicit class names (stated at compile time). In order to do a runtimecheck, you should do:

instanceof只能与显式类名(在编译时声明)一起使用。为了进行运行时检查,您应该执行以下操作:

clazz.isInstance(obj)

This has a small advantage over clazz.isAssignableFrom(..)since it deals with the case obj == nullbetter.

这有一个小的优势,clazz.isAssignableFrom(..)因为它可以obj == null更好地处理案例。

回答by Michael Aaron Safyan

Firstly, instanceofrequires that the operand on the right is an actual class (e.g. obj instanceof Objector obj instanceof Integer) and not a variable of type Class. Secondly, you have made a fairly common newbie mistake that you really should not do... the following pattern:

首先,instanceof要求右边的操作数是一个实际的类(例如obj instanceof Objectobj instanceof Integer)而不是类型的变量Class。其次,你犯了一个相当常见的新手错误,你真的不应该这样做……以下模式:

if ( conditional_expression ){
    return true;
} else{
    return false;
}

The above can be refactored into:

以上可以重构为:

return conditional_expression;

You should always perform that refactoring, as it eliminates a redundant if...else statement. Similarly, the expression return conditional_expression? true : false;is refactorable to the same result.

您应该始终执行重构,因为它消除了多余的 if...else 语句。同样,表达式可以重构为相同的结果。return conditional_expression? true : false;

回答by Rick Hanlon II

As others have mentioned, you cannot pass a class variable to instanceofbecause a class variable references an instance of an Object, while the right hand of instanceofhas to be a type. That is, instanceofdoes not mean "y is an instance of Object x", it means "y is an instance of type X". In case you don't know the difference between an Object and a type, consider:

正如其他人所提到的,您不能将类变量传递给,instanceof因为类变量引用了Object的实例,而右侧的instanceof必须是type。也就是说,instanceof并不意味着“y 是对象 x 的实例”,而是“y 是类型 X 的实例”。如果您不知道对象和类型之间的区别,请考虑:

Object o = new Object();

Object o = new Object();

Here, the type is Object, and ois a reference to the instance of the Object with that type. Thus:

在这里,类型是Object,并且o是对具有该类型的 Object 实例的引用。因此:

if(o instanceof Object)

if(o instanceof Object)

is valid but

是有效的,但是

if(o instanceof o)

if(o instanceof o)

is not because oon the right hand side is an Object, not a type.

不是因为o右手边是一个对象,而不是一个类型。

More specific to your case, a class instance is not a type, it is an Object(which is created for you by the JVM). In your method, Classis a type, but clazzis an Object (well, a reference to an Object)

更具体到您的情况,类实例不是类型,它是一个对象(由 JVM 为您创建)。在您的方法中,Class是一种类型,但是clazz是一个对象(好吧,是对对象的引用)

What you need is an way to compare an Object to a Class Object. It turns out that this is popular so this is provided to you as a method of the Class Object: isInstance().

您需要的是一种将对象与类对象进行比较的方法。事实证明这是很流行的,因此它作为 Class Object: 的方法提供给您isInstance()

Here is the Java Doc for isInstance, which explains this better:

这是 isInstance 的 Java Doc,它更好地解释了这一点:

public boolean isInstance(Object obj)

Determines if the specified Object is assignment-compatible with the object represented by this Class. This method is the dynamic equivalent of the Java language instanceof operator. The method returns true if the specified Object argument is non-null and can be cast to the reference type represented by this Class object without raising a ClassCastException. It returns false otherwise.

Specifically, if this Class object represents a declared class, this method returns true if the specified Object argument is an instance of the represented class (or of any of its subclasses); it returns false otherwise. If this Class object represents an array class, this method returns true if the specified Object argument can be converted to an object of the array class by an identity conversion or by a widening reference conversion; it returns false otherwise. If this Class object represents an interface, this method returns true if the class or any superclass of the specified Object argument implements this interface; it returns false otherwise. If this Class object represents a primitive type, this method returns false.

Parameters:obj - the object to check
Returns:true if obj is an instance of this class
Since:JDK1.1

public boolean isInstance(Object obj)

确定指定的 Object 是否与由此类表示的对象赋值兼容。此方法是 Java 语言 instanceof 运算符的动态等效方法。如果指定的 Object 参数为非 null 并且可以强制转换为由此 Class 对象表示的引用类型而不引发 ClassCastException,则该方法返回 true。否则返回 false。

具体来说,如果此 Class 对象表示一个已声明的类,并且指定的 Object 参数是所表示的类(或其任何子类)的实例,则此方法返回 true;否则返回 false。如果这个 Class 对象表示一个数组类,如果指定的 Object 参数可以通过恒等转换或扩展引用转换转换为数组类的对象,则此方法返回 true;否则返回 false。如果此 Class 对象表示一个接口,则如果指定 Object 参数的类或任何超类实现此接口,则此方法返回 true;否则返回 false。如果此 Class 对象表示原始类型,则此方法返回 false。

参数:obj - 要检查的对象
返回:如果 obj 是此类的实例,则为 true
自:JDK1.1