web-dev-qa-db-fra.com

Vérifiez si un objet est une instance d'une classe (mais pas une instance de sa sous-classe)

Pour cet exemple:

public class Foo{}

public class Bar extends Foo{}

....

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

Comment puis-je vérifier si qux est une instance de Foo (mais pas une instance de sa sous-classe de foo)? C'est:

  • checkInstance (qux, Foo.class) = true
  • checkInstance (qux, Bar.class) = false

Existe-t-il une sorte de déclaration comme instanceof pour cette vérification? ou je devrais utiliser qux.getClass().equals(Foo.class)

37
Addev

Si vous devez le faire, le seul moyen serait l'option getClass().equals(Foo.class) que vous avez suggérée.

Cependant, l'objectif de la conception OO est de vous permettre de traiter toutFoo de la même manière. Que l'instance soit ou non une sous-classe doit être hors de propos dans un programme normal.

50
Duncan Jones

Si vous recherchez une correspondance de classe exacte, le seul moyen est qux.getClass().equals(Foo.class). instanceof renverra également true pour les sous-classes.

6
nitegazer2003

vous devez utiliser instanceof

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

Cela fonctionne avec les classes et les interfaces, donc dans la plupart des cas, il devrait être préféré à .class qui ne fonctionne pas avec les interfaces.

3
Marco Forberg

J'ai juste essayé de suivre le code, cela semble bien fonctionner

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));


    }
2
Karthik Prasad
    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);
    }

}
1
boiledwater

J'ai lu toutes les réponses qui ont été publiées jusqu'à présent mais je n'ai pas encore trouvé de réponse satisfaisante. Répondre à Y a-t-il une sorte de déclaration comme instanceof pour cette vérification? Ou je devrais utiliser qux.getClass().equals(Foo.class) question je dirais oui, il y a instanceof opérateur dans Java pour vérifier si l'objet est une instance de classe. Voici un exemple-:

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");
        }
    }
}

Sortie -:

vehicle instanceof Vehicle : TRUE
vehicle instanceof Car : FALSE

car instanceof Vehicle : TRUE
car instanceof Car : TRUE

Description -:instanceof L'opérateur indique si un objet est une instance d'une classe ou s'il s'agit de classes parentes (jusqu'à n'importe quel niveau).
La ligne de sortie vehicle instanceof Car : FALSE Indique que l'opérateur instanceof ne dira pas si un objet est une instance de sa sous-classe.

Une autre façon consiste à utiliser getClass().equals(Foo.class) pour déterminer si un objet est une instance d'une classe ou non. Voyons l'exemple ci-dessous:

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");
        }


    }
}

Sortie -:

vehicle instanceof Vehicle : TRUE
vehicle instanceof Car : FALSE

car instanceof Vehicle : FALSE
car instanceof Car : TRUE

Description -: Il ressort clairement de l'exemple ci-dessus lequel (parmi les deux ci-dessus) choisir lequel?

Notes IMPORTANTES-:

  1. L'opérateur instanceof ne lèvera pas d'exception NullPointerException dans le cas où la variable de référence ne pointe vers aucun objet (c'est-à-dire qu'il a une référence nulle).
  2. car.getClass().equals(Car.class) lèvera NullPointerException exception au cas où car ne pointe sur aucun objet (c'est-à-dire qu'il a une référence nulle). Par conséquent, il faut placer une vérification null supplémentaire avec ceci par exemple car != null && car.getClass().equals(Car.class) pour l'empêcher de NullPointerException.
  3. L'opérateur instanceof indique si un objet est une instance d'une classe ou s'il s'agit de classes parentes (jusqu'à n'importe quel niveau).
  4. car.getClass().equals(Car.class) indiquera si un objet est une instance de classe uniquement. (les classes Parent & Sub ne seront pas du tout prises en compte)
1
Ashish Kumar

Eh bien, vous savez déjà que qux est une instance de Foo (à moins qu'il ne soit nul ...), donc un simple qux instanceof Bar et une vérification nulle devrait suffire.

0
vikingsteve