Есть ли в Java метод тестирования "это своего рода класс" - PullRequest
26 голосов
/ 30 мая 2009

У меня есть базовый класс, Statement, от которого наследуются несколько других классов, с именами IfStatement, WhereStatement и т. Д. ... Как лучше всего выполнить тест в операторе if, чтобы определить, какой своего рода Statement класс, из которого получен экземпляр?

Ответы [ 6 ]

74 голосов
/ 30 мая 2009
if(object instanceof WhereStatement) {
   WhereStatement where = (WhereStatement) object;
   doSomething(where);
}

Обратите внимание, что подобный код обычно означает, что в вашем базовом классе отсутствует полиморфный метод. то есть doSomething() должен быть методом Statement, возможно абстрактным, который переопределяется подклассами.

62 голосов
/ 30 мая 2009
if (obj.getClass().isInstance(Statement.class)) {
   doStuffWithStatements((Statement) obj));
}

Приятной особенностью этого метода (в отличие от ключевого слова instanceof) является то, что вы можете передавать тестовый класс как объект. Но, да, кроме этого, он идентичен "instanceof".

ПРИМЕЧАНИЕ. Я сознательно избегал редакционных публикаций о том, является ли проверка экземпляра типа правильным . Да, в большинстве случаев лучше использовать полиморфизм. Но это не то, что спросил ОП, и я просто отвечаю на его вопрос.

6 голосов
/ 30 мая 2009

Ответ на ваш вопрос - instanceof.

Однако имейте в виду, что если вашему коду нужен instanceof, это признак того, что что-то не так с вашим дизайном. Есть несколько случаев, когда instanceof оправдан, но это скорее исключения. Обычно, если ваши подклассы должны вести себя по-другому, вы должны использовать полиморфизм вместо if () s.

2 голосов
/ 20 октября 2011

isAssignableFrom (java.lang.Class) из класса - ваш ответ. http://download.oracle.com/javase/6/docs/api/java/lang/Class.html#isAssignableFrom(java.lang.Class)

1 голос
/ 08 октября 2016

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

if (Statement.class.isInstance(obj)) {
    doStuffWithStatements((Statement) obj));
}

, поскольку Метод Class.isInstance () принимает экземпляр объекта в качестве параметра.

0 голосов
/ 30 мая 2009

Это не способ делать вещи объектно-ориентированным способом, это возврат к старому дихотомии кода / данных. Теперь это не обязательно плохо (если вы знаете, что делаете), но это следует оставить необъектно-ориентированным языкам вроде C.

При правильном дизайне вам не нужно такого поведения. Вместо конструкции:

if (obj.getClass().isInstance(Statement.class)) {
    doStuffWithStatements((Statement) obj));
}

(извиняюсь перед Бенджисмитом за «кражу» его кода), вы действительно должны сделать сам объект ответственным за свою собственную деятельность таким образом:

obj.doStuff();

Тогда каждый отдельный класс obj будет иметь собственное определение для doStuff. Это правильный способ сделать это.

...