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

Instanceof дает несогласованные результаты для обнаружения интерфейсов?

Есть ли что-то сложное, что я должен знать о instanceof? Я передаю список объектов несколькими методами и проверяю, реализуют ли эти объекты определенный интерфейс с помощью instanceof. В некоторых случаях instanceof правильно идентифицирует объекты как реализующие интерфейс, в других случаях это не так. Кажется, это дает мне непоследовательные результаты на одном и том же объекте в разных местах. Есть ли трюк /gotcha, о котором я должен знать здесь?

В ожидании комментариев у вас может быть:

1) Я знаю, что instanceof - плохая форма. Я работаю с менее совершенной иерархией объектов, которые нельзя изменить, и это самая плохая вещь, которую я могу думать.

2) Я работаю над созданием примера кода, но мне нужно будет упростить мой код, если я собираюсь вставить что-нибудь полезное здесь. Тем временем, если вы видели это раньше и можете пролить свет, сделайте это.

4b9b3361

Ответ 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 для классов, реализующих ваш интерфейс.