为什么这段代码不能编译?
public boolean isOf(Class clazz, Object obj){
if(obj instanceof clazz){
return true;
}else{
return false;
}
}
为什么我无法将类变量传递给instanceof
?
答案 0 :(得分:119)
instanceof
运算符适用于Integer
等引用类型,而不适用于new Integer(213)
等对象。你可能想要像
clazz.isInstance(obj)
旁注:如果你写
,你的代码会更简洁public boolean isOf(Class clazz, Object obj){
return clazz.isInstance(obj)
}
不确定你是否还需要一种方法。
答案 1 :(得分:12)
instanceof
只能用于显式类名(在编译时声明)。要进行运行时检查,您应该执行以下操作:
clazz.isInstance(obj)
这比clazz.isAssignableFrom(..)
有一个小优势,因为它更好地处理案例obj == null
。
答案 2 :(得分:3)
首先,instanceof
要求右侧的操作数是实际的类(例如obj instanceof Object
或obj instanceof Integer
),而不是Class
类型的变量。其次,你做了一个相当常见的新手错误,你真的不应该做......以下模式:
if ( conditional_expression ){ return true; } else{ return false; }
以上内容可以重构为:
return conditional_expression;
您应该始终执行该重构,因为它消除了冗余的if ... else语句。同样,表达式return conditional_expression ? true : false;
可以重构为相同的结果。
答案 3 :(得分:3)
正如其他人所提到的,你不能将类变量传递给instanceof
,因为类变量引用 Object 的实例,而instanceof
的右手必须是一个类型。也就是说,instanceof
并不意味着“y是对象x的实例”,它意味着“y是类型X的实例”。如果您不知道Object和类型之间的区别,请考虑:
Object o = new Object();
此处,类型为Object
,o
是对具有该类型的Object实例的引用。因此:
if(o instanceof Object)
有效,但
if(o instanceof o)
不是因为右侧的o
是对象,而不是类型。
更具体的情况是,类实例不是类型,它是 Object (由JVM为您创建)。在您的方法中,Class
是一种类型,但clazz
是一个对象(嗯,对象的引用)
您需要的是一种将对象与类对象进行比较的方法。事实证明这很受欢迎,所以这是作为类对象的方法提供给你的:isInstance()
。
以下是isInstance的Java Doc,它更好地解释了这一点:
public boolean isInstance(Object obj)
确定指定的Object是否与赋值兼容 此类所代表的对象。这种方法是动态的 相当于Java语言instanceof运算符。方法 如果指定的Object参数为非null且可以,则返回true 强制转换为此Class对象表示的引用类型 引发ClassCastException。否则返回false。
具体来说,如果这个Class对象代表一个声明的类,那么这个 如果指定的Object参数是实例,则method返回true 表示的类(或其任何子类);它返回false 除此以外。如果此Class对象表示数组类,则此方法 如果指定的Object参数可以转换为,则返回true 数组类的对象,通过标识转换或扩展 参考转换;否则返回false。如果是这个Class对象 表示一个接口,如果该类或任何类,则此方法返回true 指定Object参数的超类实现此接口; 否则返回false。如果这个Class对象代表一个 原始类型,此方法返回false。
参数: obj - 要检查的对象
返回:如果obj是此类的实例,则为true 自: JDK1.1