检查对象是否是类的实例(但不是其子类的实例)

时间:2013-05-22 09:48:20

标签: java instanceof

对于这个例子:

public class Foo{}

public class Bar extends Foo{}

....

void myMethod(Foo qux){
   if (checkInstance(qux,Foo.class)){
     ....
   }
}

如何检查qux是否为Foo的实例(但不是foo子类的实例)?那就是:

  • checkInstance(qux,让Foo.class)=真
  • checkInstance(qux,Bar.class)=假

此检查是否有类似instanceof的声明?或者我应该使用qux.getClass().equals(Foo.class)

7 个答案:

答案 0 :(得分:49)

如果必须这样做,唯一的方法就是您建议的getClass().equals(Foo.class)选项。

但是,OO设计的目标是允许您以相同的方式处理任何 Foo。实例是否是子类在正常程序中应该是无关紧要的。

答案 1 :(得分:6)

如果您正在寻找精确的课程匹配,唯一的方法是qux.getClass().equals(Foo.class)。 instanceof也会为子类返回true。

答案 2 :(得分:3)

你应该使用instanceof

if(qux instanceof Foo && !(qux instanceof Bar)) {
    ...
}

这适用于类和接口,因此在大多数情况下,它应优先于.class,而不适用于接口。

答案 3 :(得分:2)

我刚试过以下代码,看起来工作正常

public class BaseClass {

    private String a;

    public boolean isInstanceOf(BaseClass base){
        if(base == null){
            return false;
        }
        else if(getClass() == base.getClass()){
            return true;
        }else{
            return false;
        }
    }

}



public class DervidClass extends BaseClass {


    public boolean isInstanceOf(DervidClass base) {
        if(base == null){
            return false;
        }
        else if(getClass() == base.getClass()){
            return true;
        }else{
            return false;
        }
    }


}

public class myTest {
public static void main(String[] args) throws ParseException {


        BaseClass base = new BaseClass();
        BaseClass base1 = new BaseClass();
        DervidClass derived = new DervidClass();

        BaseClass d1 = new DervidClass();

        System.out.println(base.isInstanceOf(d1));
        System.out.println(d1.isInstanceOf(d1));
        System.out.println((d1 instanceof BaseClass));


    }

答案 4 :(得分:1)

    package com.instance;

    public class Foo {
        public void instance(Foo f) {
            System.out.println("---------");
            System.out.println(f.getClass());
            System.out.println(getClass());
            if (f.getClass() == getClass()) {
                System.out.println("Yes");
            } else {
                System.out.println("No");
            }
        }
    }


package com.instance;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Foo f1 = new Foo();
        Foo f2 = new Foo();
        Foo f3 = new Bar();
        f1.instance(f1);
        f1.instance(f2);
        f1.instance(f3);
    }

}

答案 5 :(得分:1)

我已经阅读了迄今为止发布的所有答案,但还没有找到满意的答案。回答此检查是否有某种类似instanceof的声明?或者我应该使用qux.getClass().equals(Foo.class) 问题我会说是,java中有instanceof运算符来检查对象是否是类的实例。下面是一个例子 - :

class Vehicle {

}

class Car extends Vehicle {

}

public class Research {
    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();

        if (vehicle instanceof Vehicle) {
            System.out.println("vehicle instanceof Vehicle : TRUE");
        } else {
            System.out.println("vehicle instanceof Vehicle : FALSE");
        }

        if (vehicle instanceof Car) {
            System.out.println("vehicle instanceof Car : TRUE");
        } else {
            System.out.println("vehicle instanceof Car : FALSE");
        }

        System.out.println();
        Car car = new Car();

        if (car instanceof Vehicle) {
            System.out.println("car instanceof Vehicle : TRUE");
        } else {
            System.out.println("car instanceof Vehicle : FALSE");
        }

        if (car instanceof Car) {
            System.out.println("car instanceof Car : TRUE");
        } else {
            System.out.println("car instanceof Car : FALSE");
        }
    }
}

<强>输出 - :

vehicle instanceof Vehicle : TRUE
vehicle instanceof Car : FALSE

car instanceof Vehicle : TRUE
car instanceof Car : TRUE

描述 - : instanceof运算符告诉对象是类的实例还是它的父类(最高级别)。
vehicle instanceof Car : FALSE输出行表示instanceof运算符不会判断对象是否是其子类的实例。

另一种方法是使用getClass().equals(Foo.class)来确定对象是否是类的实例。让我们看下面的例子 - :

class Vehicle {

}

class Car extends Vehicle {

}

public class Research {
    public static void main(String[] args) {
        Vehicle vehicle = new Vehicle();

        if (vehicle.getClass().equals(Vehicle.class)) {
            System.out.println("vehicle instanceof Vehicle : TRUE");
        } else {
            System.out.println("vehicle instanceof Vehicle : FALSE");
        }

        if (vehicle.getClass().equals(Car.class)) {
            System.out.println("vehicle instanceof Car : TRUE");
        } else {
            System.out.println("vehicle instanceof Car : FALSE");
        }

        System.out.println();
        Car car = new Car();

        if (car.getClass().equals(Vehicle.class)) {
            System.out.println("car instanceof Vehicle : TRUE");
        } else {
            System.out.println("car instanceof Vehicle : FALSE");
        }

        if (car.getClass().equals(Car.class)) {
            System.out.println("car instanceof Car : TRUE");
        } else {
            System.out.println("car instanceof Car : FALSE");
        }


    }
}

<强>输出 - :

vehicle instanceof Vehicle : TRUE
vehicle instanceof Car : FALSE

car instanceof Vehicle : FALSE
car instanceof Car : TRUE

说明 - :从上面的例子中可以清楚地知道哪一个(上面两个)应该选择在哪里?

  

重要说明 - :

    如果引用变量没有指向任何对象(即它具有空引用),
  1. instanceof运算符将不会抛出NullPointerException异常。
  2. 如果car.getClass().equals(Car.class)未指向任何对象(即其具有空引用),
  3. NullPointerException将抛出car异常。因此,必须对此进行额外的空值检查,例如car != null && car.getClass().equals(Car.class),以防止它NullPointerException
  4. instanceof运算符告诉对象是类的实例还是它的父类(直到任何级别)。
  5. car.getClass().equals(Car.class)将告诉对象是否只是类的实例。 (根本不会考虑家长和子类)

答案 6 :(得分:0)

你已经知道qux是foo的instanceof(除非它是null ...),所以你应该只需要一个简单的qux instanceof Bar和一个空检查。