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


89

为什么此代码无法编译?

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

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

Answers:


131

instanceof操作符对引用类型,像Integer,而不是对象,如new Integer(213)。您可能想要类似

clazz.isInstance(obj)

旁注:如果编写,您的代码将更加简洁

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

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


我知道代码完全没用,我只是想证明我的困惑:)
eric2323223'4

6
Integer不是一类的文字。Integer.class将是类文字(请参见JLS的第15.8.2节:java.sun.com/docs/books/jls/third_edition/html/…)。在instanceof操作者需要一个“引用类型”(又名类型名)作为指定的§JLS的15.20.2:java.sun.com/docs/books/jls/third_edition/html/...
勒夫绍尔

3
我会用,clazz.isInstance(obj)因为已经提供了对象。
Donal Fellows 2010年

13

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

clazz.isInstance(obj)

clazz.isAssignableFrom(..)与之相比,它具有较小的优势,因为它可以obj == null更好地处理案件。


5

正如其他人提到的那样,您不能将类变量传递给,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文档,它对此进行了更好的解释:

public boolean isInstance(Object obj)

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

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

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


3

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

如果(conditional_expression){
    返回true;
}其他{
    返回false;
}

以上内容可以重构为:

返回conditional_expression ;

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


2
没错 也许笨拙,但完全可以。在可预见的将来返回之前,也许您需要其他代码...
令人难以置信的
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.