为什么这段代码不能编译?
public boolean isOf(Class clazz, Object obj){
if(obj instanceof clazz){
return true;
}else{
return false;
}
}
为什么我不能将类变量传递给instanceof
?
为什么这段代码不能编译?
public boolean isOf(Class clazz, Object obj){
if(obj instanceof clazz){
return true;
}else{
return false;
}
}
为什么我不能将类变量传递给instanceof
?
该instanceof
运算符适用于引用类型,如Integer
,而不适用于对象,如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
因为类变量引用Object的实例,而右手instanceof
必须是type。也就是说,instanceof
并不表示“y 是对象 x 的实例”,而是表示“y 是类型 X 的实例”。如果您不知道对象和类型之间的区别,请考虑:
Object o = new Object();
在这里,类型是Object
,并且o
是对具有该类型的 Object 实例的引用。因此:
if(o instanceof Object)
有效但
if(o instanceof o)
不是因为o
右边是一个对象,而不是一个类型。
更具体到您的情况,类实例不是类型,它是一个对象(由 JVM 为您创建)。在你的方法中,Class
是一个类型,但是clazz
是一个对象(嗯,一个对象的引用)
您需要一种将对象与类对象进行比较的方法。事实证明,这很受欢迎,因此作为 Class Object: 的方法提供给您isInstance()
。
这是 isInstance 的 Java Doc,它更好地解释了这一点:
public boolean isInstance(Object obj)
确定指定的 Object 是否与该 Class 表示的对象赋值兼容。此方法是 Java 语言 instanceof 运算符的动态等效方法。如果指定的 Object 参数不为 null,则该方法返回 true,并且可以强制转换为此 Class 对象表示的引用类型,而不会引发 ClassCastException。否则返回 false。
具体来说,如果此 Class 对象表示已声明的类,则如果指定的 Object 参数是表示的类(或其任何子类)的实例,则此方法返回 true;否则返回 false。如果此 Class 对象表示一个数组类,如果指定的 Object 参数可以通过恒等转换或扩展引用转换转换为数组类的对象,则此方法返回 true;否则返回 false。如果此 Class 对象表示一个接口,则如果指定 Object 参数的类或任何超类实现此接口,则此方法返回 true;否则返回 false。如果此 Class 对象表示原始类型,则此方法返回 false。
参数: obj - 要检查的对象
返回:如果 obj 是此类的实例,则返回 true
自: JDK1.1
首先,instanceof
要求右边的操作数是一个实际的类(例如obj instanceof Object
or obj instanceof Integer
)而不是类型的变量Class
。其次,你犯了一个相当常见的新手错误,你真的不应该这样做......以下模式:
如果(条件表达式){ 返回真; } 别的{ 返回假; }
以上可以重构为:
返回条件表达式;
您应该始终执行该重构,因为它消除了多余的 if...else 语句。同样,表达式可重构为相同的结果。return conditional_expression ? true : false;