Instanceof дает несогласованные результаты для обнаружения интерфейсов?
Есть ли что-то сложное, что я должен знать о instanceof
? Я передаю список объектов несколькими методами и проверяю, реализуют ли эти объекты определенный интерфейс с помощью instanceof
. В некоторых случаях instanceof
правильно идентифицирует объекты как реализующие интерфейс, в других случаях это не так. Кажется, это дает мне непоследовательные результаты на одном и том же объекте в разных местах. Есть ли трюк /gotcha, о котором я должен знать здесь?
В ожидании комментариев у вас может быть:
1) Я знаю, что instanceof
- плохая форма. Я работаю с менее совершенной иерархией объектов, которые нельзя изменить, и это самая плохая вещь, которую я могу думать.
2) Я работаю над созданием примера кода, но мне нужно будет упростить мой код, если я собираюсь вставить что-нибудь полезное здесь. Тем временем, если вы видели это раньше и можете пролить свет, сделайте это.
Ответы
Ответ 1
Загружаете ли вы какие-либо типы динамически, потенциально из разных загрузчиков классов? Единственный раз, когда я видел, по-видимому, непоследовательные результаты, было то, что у меня было две строки кода, которые выглядят так, как будто они относятся к одному типу, но которые действительно загружали этот тип из разных загрузчиков классов.
Ответ 2
instanceof
всегда возвращает false
для null
. Он не компилируется, если было бы невозможно, чтобы статический тип слева не мог быть экземпляром указанного типа. Помимо этого, он должен работать без особого удивления.
В отличие от С++ (и я считаю Smalltalk), объект не может изменять тип во время выполнения. В С++ тип изменяется во время построения, поэтому методы не могут быть вызваны из метода конструктора в производный класс [подкласс].
Ответ 3
Хорошо, проблема решена. Как обычно, проблема была менее странной, чем я думал. Проект, над которым я работаю, находится в неудачном состоянии наличия дубликатов имен классов. Я создавал класс, используя foo.MyInterface и тестируя, например, bar.MyInterface. Спасибо за ответы. Это действительно помогло мне продумать это.
Ответ 4
Единственное, что я знаю о том, что null
- это instanceof
no type.
Ответ 5
Пока у вас нет проблемы с загрузкой классов, instanceof работает последовательно.
Я думаю, вы знаете, что экземпляр B возвращает true, если A наследуется от B, или некоторые из интерфейсов A реализует или расширяет классы A, являются экземплярами B.
Если вы получаете false, когда вы ожидаете true, вы, вероятно, пытаетесь сравнить экземпляры, поступающие с разных классов ClassLoaders.
Ответ 6
Возможно, вы захотите "isAssignable" вместо instanceof:
if (MyInterface.isAssignableFrom(myObject.getClass())) {
// do work here
}
Это вернет true для классов, реализующих ваш интерфейс.