Сравнение типов классов в Java - PullRequest
44 голосов
/ 27 мая 2011

Я хочу сравнить тип класса в Java.

Я думал, что смогу сделать это:

class MyObject_1 {}
class MyObject_2 extends MyObject_1 {}

public boolean function(MyObject_1 obj) {
   if(obj.getClass() == MyObject_2.class) System.out.println("true");
}

Я хотел сравнить в случае, если объект, переданный в функцию, был расширениз MyObject_1 или нет.Но это не работает.Похоже, что метод getClass () и .class предоставляют информацию разного типа.

Как можно сравнить два типа классов, не создавая другой фиктивный объект просто для сравнения типа класса?

Ответы [ 7 ]

47 голосов
/ 27 мая 2011

Попробуйте это:

MyObject obj = new MyObject();
if(obj instanceof MyObject){System.out.println("true");} //true

Из-за наследования это справедливо и для интерфейсов:

class Animal {}
class Dog extends Animal {}    

Dog obj = new Dog();
Animal animal = new Dog();
if(obj instanceof Animal){System.out.println("true");} //true
if(animal instanceof Animal){System.out.println("true");} //true
if(animal instanceof Dog){System.out.println("true");} //true

Для дальнейшего чтения на instanceof: http://mindprod.com/jgloss/instanceof.html

30 голосов
/ 27 мая 2011

Если вы не хотите или не можете использовать instanceof, то сравните с equals:

 if(obj.getClass().equals(MyObject.class)) System.out.println("true");

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

  • классы имеют одинаковое короткое имя, но определены в разных пакетах
  • классы имеют одинаковое полное имя, но загруженыразными загрузчиками классов.
10 голосов
/ 27 мая 2011

Он печатает true на моей машине. И это должно произойти, иначе ничто в Java не будет работать как ожидалось (Это объясняется в JLS: 4.3.4, когда ссылочные типы одинаковы )

Есть ли у вас несколько загрузчиков классов?


Ах, и в ответ на этот комментарий:

Я понимаю, что у меня есть опечатка в моем вопрос. Я должен быть таким:

MyImplementedObject obj = new MyImplementedObject ();
if(obj.getClass() == MyObjectInterface.class) System.out.println("true");

MyImplementedObject реализует MyObjectInterface Итак, другими словами, я сравниваю его с реализованным объекты.

ОК, если вы хотите проверить, что вы можете сделать:

if(MyObjectInterface.class.isAssignableFrom(obj.getClass()))

или гораздо более краткий

if(obj instanceof MyobjectInterface)
3 голосов
/ 20 сентября 2013

Как уже говорилось ранее, ваш код будет работать, если у вас не загружены одинаковые классы на двух разных загрузчиках классов. Это может произойти в том случае, если вам нужно одновременно хранить несколько версий одного и того же класса в памяти, или вы выполняете какие-то странные компиляции на лету (как и я).

В этом случае, если вы хотите считать их одним и тем же классом (что может быть разумным в зависимости от ситуации), вы можете сопоставить их имена для сравнения.

public static boolean areClassesQuiteTheSame(Class<?> c1, Class<?> c2) {
  // TODO handle nulls maybe?
  return c1.getCanonicalName().equals(c2.getCanonicalName());
}

Имейте в виду, что это сравнение будет делать то, что оно делает: сравнивать имена классов; Я не думаю, что вам удастся привести одну версию класса к другой, и, прежде чем заглянуть в рефлексию, вы можете убедиться, что есть веская причина для беспорядка в загрузчике классов.

1 голос
/ 24 января 2015

Проверьте исходный код Class.java на наличие равных ()

public boolean equals(Object obj) {
return (this == obj);
}
0 голосов
/ 14 июля 2019

Сравнение объекта с классом с использованием instanceOf или ... уже получено.

Если у вас есть два объекта и вы хотите сравнить их типы с друг с другом , вы можете использовать:

if (obj1.getClass() == obj2.getClass()) {
   // Both have the same type
}
0 голосов
/ 23 сентября 2016

Хммм ... Имейте в виду, что Class может реализовывать или не использовать equals () - что не требуется в спецификации.Например, HP Fortify будет отмечать myClass.equals (myOtherClass).

...