Как я могу узнать, являются ли два аргумента экземплярами одного и того же, но неизвестного класса? - PullRequest
1 голос
/ 17 апреля 2010

Допустим, у нас есть метод, который принимает два аргумента o1 и o2 типа Object и возвращает логическое значение. Я хочу, чтобы этот метод возвращал значение true, только когда аргументы являются экземплярами одного и того же класса, например ::10000

foo(new Integer(4),new Integer(5));

Должен вернуть true, однако:

foo(new SomeClass(), new SubtypeSomeClass());

должен вернуть false, а также:

foo(new Integer(3),"zoo");

должен вернуть false.

Я полагаю, что один из способов - сравнить полные имена классов:

public boolean foo(Object o1, Object o2){
 Class<? extends Object> c1 = o1.getClass();
 Class<? extends Object> c2 = o2.getClass();
 if(c1.getName().equals(c2.getName()){ return true;}
 return false;  
}

Альтернативный условный оператор будет:

if (c1.isAssignableFrom(c2) && c2.isAssignableFrom(c1)){ return true; }

Последняя альтернатива довольно медленная. Есть ли другие варианты этой проблемы?

Ответы [ 2 ]

10 голосов
/ 17 апреля 2010

Не беспокойтесь о полных именах классов - просто сравните ссылки на классы:

public boolean foo(Object o1, Object o2) {
    return o1.getClass() == o2.getClass();
}

Классы по сути уникальны по имени и загрузчику классов - поэтому будет возвращено значение false, если объекты одного и того же класса имя , но загружены разными загрузчиками классов, но это, вероятно, уместно: они могут быть совершенно разными классами в все кроме имени! Однако, если классы имеют одинаковое имя и загрузчик классов, они будут иметь одинаковую ссылку.

Обратите внимание, что это выдаст NullPointerException, если либо o1, либо o2 равно нулю, но, опять же, это, вероятно, то, что вы хотите.

0 голосов
/ 17 апреля 2010

Можете ли вы пройти довольно медленно? По сравнению с чем? Также, пожалуйста, уточните свой сценарий использования? В java Object api включает метод сравнения equals / hashCode, который должен использоваться для определения равенства между объектами. Похоже, это то, что вы пытаетесь найти, например:

new Integer(4).equals(new Integer(5))

В этом случае лучшая реализация для переопределения equals в SomeClass выглядит следующим образом:

public boolean equals(Object obj) {
    if (obj instanceof SomeClass) {
        return ((SomeClass) obj).identityField.equals(identityField);
    }
    return false;
}
public int hashCode() {
    return 31 * identity.hashCode();
}

Убедившись, что вы указали личность внутри вашего объекта.

...