代码之家  ›  专栏  ›  技术社区  ›  eric2323223

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

  •  76
  • eric2323223  · 技术社区  · 15 年前

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

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

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

    4 回复  |  直到 8 年前
        1
  •  118
  •   Robert Munteanu    15 年前

    这个 instanceof 运算符处理引用类型,例如 Integer 而不是在物体上,比如 new Integer(213) . 你可能想要类似的东西

    clazz.isInstance(obj)
    

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

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

    但是,不确定是否需要一个方法。

        2
  •  12
  •   Alex Ling Zhong    8 年前

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

    clazz.isInstance(obj)
    

    这比 clazz.isAssignableFrom(..) 因为它处理这个案子 obj == null 更好。

        3
  •  3
  •   Michael Aaron Safyan    15 年前

    首先, 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; 可重构为相同的结果。

        4
  •  3
  •   Rick Hanlon II    12 年前

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

    Object o = new Object();

    这里,类型是 Object o 是对具有该类型的对象实例的引用。因此:

    if(o instanceof Object)

    有效,但

    if(o instanceof o)

    不是因为 o 在右手边是一个对象,而不是类型。

    更具体地说,类实例不是类型,它是 对象 (由JVM为您创建)。在你的方法中, Class 是一种类型,但是 clazz 是一个对象(对对象的引用)

    您需要的是一种将对象与类对象进行比较的方法。结果发现这很流行,所以作为类对象的一种方法提供给您: isInstance()

    下面是iSimple的Java文档,它解释得更好:

    public boolean isInstance(Object obj)

    确定指定对象的赋值是否与 由此类表示的对象。这种方法是动态的 相当于操作员的Java语言实例。方法 如果指定的对象参数为非空且可以为 强制转换为此类对象表示的引用类型 引发ClassCastException。否则返回false。

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

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