为什么不能将“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 Object
或obj 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是Object
, o
是对该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