为什么不能将“Class”variables传递给instanceof?

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

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

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

instanceof运算符对像Integer这样的引用types进行处理,而不是对象,比如new Integer(213) 。 你可能想要类似的东西

 clazz.isInstance(obj) 

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

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

但是,不确定是否需要一种方法。

instanceof只能用于显式类名(在编译时声明)。 为了做一个运行时检查,你应该这样做:

 clazz.isInstance(obj) 

这比clazz.isAssignableFrom(..)有一个小优点,因为它处理的情况obj == null更好。

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

 if( conditional_expression ){
    返回true;
 } else {
    返回false;
 }

以上可以重构为:

返回条件expression式 ;

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

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

Object o = new Object();

这里的types是Objecto是对该types的Object的实例的引用。 从而:

if(o instanceof Object)

是有效的但是

if(o instanceof o)

不是因为在右边是一个对象,而不是一个types。

更具体到你的情况,一个类实例不是一个types,它是一个对象 (它是由JVM为你创build的)。 在你的方法中, Class是一个types,但clazz是一个对象(以及对一个对象的引用)

你需要的是一种将对象与类对象进行比较的方法。 事实certificate,这是stream行的,所以这是作为类对象的方法提供给你的: isInstance()

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

public boolean isInstance(Object obj)

确定指定的Object是否与此Class所表示的对象分配兼容。 这个方法是Java语言instanceof操作符的dynamic等价物。 如果指定的Object参数是非空的,则该方法返回true,并且可以将其转换为由此Class对象表示的引用types,而不引发ClassCastException。 否则返回false。

具体而言,如果此Class对象表示一个声明的类,则此方法返回true,如果指定的Object参数是表示的类(或其任何子类)的实例; 否则返回false。 如果此Class对象表示一个数组类,则如果通过标识转换或扩展引用转换将指定的Object参数转换为数组类的对象,则此方法返回true; 否则返回false。 如果此Class对象表示一个接口,则此方法返回true,如果指定Object参数的类或任何超类实现此接口; 否则返回false。 如果此Class对象表示一个基本types,则此方法返回false。

参数: obj – 要检查的对象
返回:如果obj是此类的一个实例,则返回 true
以下版本开始 JDK1.1