Подтвердить что ты не робот

Сравнение типов классов в Java

Я хочу сравнить тип класса в 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");
}

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

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

4b9b3361

Ответ 1

Попробуйте следующее:

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

Ответ 2

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

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

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

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

Ответ 3

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

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


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

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

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)

Ответ 4

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

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

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

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

Ответ 5

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

public boolean equals(Object obj) {
return (this == obj);
}

Ответ 6

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

Ответ 7

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

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

if (obj1.getClass() == obj2.getClass()) {
   // Both have the same type
}