Праверце, калі аб'ект з'яўляецца асобнікам класа (але не асобнік падкласа)

Для гэтага прыкладу:

public class Foo{}

public class Bar extends Foo{}

....

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

Як я магу праверыць, калі QUX з'яўляецца асобнікам Foo (але не асобнік падкласа абуўшы)? Гэта:

    <�Літый> checkInstance (QUX, Foo.class) = TRUE <�Літый> checkInstance (QUX, Bar.class) = False

Is there some kind of statement like instanceof for this check? or I should use qux.getClass().equals(Foo.class)

28
але праверка, калі аб'ект з'яўляецца асобнікам Foo, але не Bar (калі Bar праходзіць Foo) няправільна дызайн прыкладання
дададзена аўтар Selvin, крыніца
@Selvin Выкарыстання InstanceOf не абавязкова азначае, што дызайн прыкладання з'яўляецца няправільным. Напрыклад, ён выкарыстоўваецца ў адаптарах, калі вы спрабуеце адлюстраваць дадзеныя для некалькіх тыпаў прадстаўлення.
дададзена аўтар Dazzy_G, крыніца
дададзена аўтар DaGLiMiOuX, крыніца

7 адказы

Калі вы павінны зрабіць гэта, адзіным спосабам было б GetClass (). Equals (Foo.class) варыянт вы прапанавалі.

Тым не менш, мэта дызайну OO, каб дазволіць вам лячыць любы Foo такім жа чынам. Будзьце ці не асобнік з'яўляецца падклас павінен быць недарэчны ў звычайнай праграме.

43
дададзена
Я не разумею, што такое <�я> лепшая альтэрнатыва </я> што <�я> супадаюць з прынцыпамі ГА
дададзена аўтар ycomp, крыніца
хмм, я думаю, адлучаючы Foo на 2 класа Foo і SuperFoo і ёсць Бар спусціцца з SuperFoo можа быць нейкім чынам фальсіфікаваць яго, але код стане больш складаным з-за гэтага. Так што гэта можа быць больш OO, але я не ўпэўнены, што гэта лепш.
дададзена аўтар ycomp, крыніца
ОК, так як у мяне ёсць IDE, які можа рэфактарынг, гэта тое, што я буду рабіць), можа быць, гэта пазбавіць мяне ад некаторых памылак у будучыні (althpugh Я аддаю перавагу прэфікс Анатацыя у Super , гэта проста я не магу рэдагаваць старыя каментары)
дададзена аўтар ycomp, крыніца
@WarrenDew я згодны. Але высокі адсотак людзі шукаюць спосаб рэалізаваць сваё ўласнае рашэнне праблемы, калі, магчыма, лепшае рашэнне існуе. Калі вы апыняецеся парушаючы прынцыпы ГА ў ГА-мове, гэта вельмі добрая прыкмета, што вы па-за трас.
дададзена аўтар Duncan Jones, крыніца
Я думаю, што шмат пытанняў абмену насцілу пра сітуацыі, якія знаходзяцца па-за нармальных.
дададзена аўтар Warren Dew, крыніца
Як наконт таго выпадку, калі вы перакрываючы роўны функцыі? Я павінен быць упэўнены, што аб'ект Я параўноўваю свой аб'ект, таго ж класа, а не падкласа. Я не хачу Менеджэр аб'ект роўным да Employee аб'екта. У адваротным выпадку, гэта парушыла б характарыстыку добрага роўны функцыя: «x.equals (у) павінна вяртаць праўдзівая тады і толькі тады, калі y.equals (х) вяртае ісціну».
дададзена аўтар John Red, крыніца
У модульным цесцю вы, верагодна, хочаце, каб праверыць для дакладнага класа, а не выкарыстоўваць InstanceOf
дададзена аўтар anttikoo, крыніца

Калі вы шукаеце дакладнае адпаведнасць класа адзіным сродкам з'яўляецца qux.getClass (). Роўна (Foo.class) . InstanceOf таксама вяртае ісціну для падкласаў.

6
дададзена

Вы павінны выкарыстоўваць InstanceOf

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

Гэта працуе з абодвух класаў і інтэрфейсаў, так што ў большасці выпадкаў яна павінна пераважней .class , які не працуе з інтэрфейсамі.

3
дададзена
Гэта не будзе лавіць сітуацыю дзе Баз з'яўляецца падклас Foo .
дададзена аўтар Duncan Jones, крыніца
Хай Баз з'яўляецца прамым падклас Foo . Абодва бакі вашага , калі пункт будзе вылічвацца True .
дададзена аўтар Duncan Jones, крыніца
Так. <�Код> Баз не з'яўляецца асобнікам Bar ў маім прыкладзе. Звярніце ўвагу, што я крыху які распасціраецца арыгінальны прыклад аперацыйнага каб абмеркаваць агульны выпадак.
дададзена аўтар Duncan Jones, крыніца
гэта так? правая частка && павінен вяртаць хлусня для асобнікаў Bar незалежна ад таго, што іншыя класы не распаўсюджваецца
дададзена аўтар Marco Forberg, крыніца
вы бачыце , ці не так?
дададзена аўтар Marco Forberg, крыніца
добра зразумелі ОП. Думаў ён хацеў, каб выключыць толькі адзін падклас і хай іншыя падкласы па-ранейшаму вядуць сябе так жа, як базавы клас і я да гэтага часу не ведаю, чаму адзін павінен хацець зрабіць гэта такім чынам
дададзена аўтар Marco Forberg, крыніца

Я проста паспрабаваў наступны код, здаецца, працуе нармальна

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
дададзена
    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
дададзена
Карціна можа намаляваць тысячу слоў, але вялікі кавалак кода упэўнены, робіць непрыгожы адказ.
дададзена аўтар Duncan Jones, крыніца

Я прачытаў усе адказы, якія былі апублікаваныя да гэтага часу, але не змог знайсці здавальняючы адказ. Адказ на <�моцны> Ці ёсць нейкія заявы, як InstanceOf для гэтай праверкі? ці я павінен выкарыстоўваць qux.getClass (). Equals (Foo.class) пытанне, я б сказаў, так, ёсць InstanceOf аператар у Java, каб праверыць, аб'ект з'яўляецца асобнікам класа. Ніжэй прыводзіцца прыкладны:

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

Description-:instanceof operator tells if an object is a instance of a class or it's parent classes (up to any level).
vehicle instanceof Car : FALSE line of output is indicating that instanceof operator will not tell if an object is a instance of its sub class.

Іншы спосаб складаецца ў выкарыстанні GetClass (). Роўна (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

Description-: It would be clear from the above example that which one(out of above two) should be opted where?

<�Р> Важныя заўвагі -
  1. instanceof operator will not throw NullPointerException exception in case if reference variable is not pointing to any object(i.e. its having null reference).
  2. car.getClass().equals(Car.class) will throw NullPointerException exception in case if car is not pointing to any object(i.e. its having null reference). Therefore one must place extra null check with this for example car != null && car.getClass().equals(Car.class) to prevent it from NullPointerException.
  3. instanceof operator tells if an object is a instance of a class or it's parent classes (up to any level).
  4. car.getClass().equals(Car.class) will tell if an object is a instance of class only. (Parent & Sub classes will not be considered at all)
1
дададзена
Гэта сумна. Такія намаганні, каб адказаць на пытанне, які не быў зададзены.
дададзена аўтар comodoro, крыніца

Ну, вы ўжо ведаеце, што QUX з'яўляецца InstanceOf Foo (калі гэта не пусты ...), таму просты QUX InstanceOf Bar і праверка нуль павінна быць усё, што вам трэба.

0
дададзена