【问题标题】:Why can't a "Class" variable be passed to instanceof?为什么不能将“类”变量传递给 instanceof?
【发布时间】:2011-02-05 03:31:12
【问题描述】:

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

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

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

【问题讨论】:

    标签: java class instanceof


    【解决方案1】:

    instanceof 只能与明确的类名一起使用(在编译时声明)。为了进行 runtime 检查,您应该:

    clazz.isInstance(obj)
    

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

    【讨论】:

      【解决方案2】:

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

      Object o = new Object();

      这里,类型是Objecto 是对具有该类型的 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 并且可以是 强制转换为此 Class 对象表示的引用类型 引发 ClassCastException。否则返回 false。

      具体来说,如果这个 Class 对象代表一个声明的类,这个 如果指定的 Object 参数是 代表的类别(或其任何子类别);它返回假 否则。如果这个 Class 对象代表一个数组类,这个方法 如果指定的 Object 参数可以转换为 数组类的对象通过身份转换或扩大 参考转换;否则返回 false。如果这个 Class 对象 表示一个接口,如果类或任何类,此方法返回 true 指定 Object 参数的超类实现此接口; 否则返回 false。如果这个 Class 对象代表一个 原始类型,该方法返回false。

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

      【讨论】:

        【解决方案3】:

        instanceof 运算符适用于引用类型,如 Integer,而不适用于对象,如 new Integer(213)。你可能想要类似的东西

        clazz.isInstance(obj)
        

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

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

        不过,不确定您是否还需要一个方法。

        【讨论】:

        【解决方案4】:

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

        if ( 条件表达式 ){ 返回真; } 别的{ 返回假; }

        上面可以重构为:

        返回条件表达式

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

        【讨论】:

        • 没错。也许笨拙但总体还可以。也许您在可预见的将来返回之前需要额外的代码......
        猜你喜欢
        • 2019-03-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-05-01
        • 1970-01-01
        • 2020-07-15
        • 1970-01-01
        相关资源
        最近更新 更多