instanceof дает противоречивые результаты для обнаружения интерфейсов? - PullRequest
12 голосов
/ 10 марта 2009

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

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

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

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

Ответы [ 6 ]

14 голосов
/ 10 марта 2009

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

9 голосов
/ 10 марта 2009

Хорошо, проблема решена. Как обычно, проблема оказалась менее странной, чем я думал. Проект, над которым я работаю, находится в плачевном состоянии, имея несколько повторяющихся имен классов. Я создавал класс с использованием foo.MyInterface и тестировал, например, bar.MyInterface. Спасибо за ответы. Это действительно помогло мне обдумать это.

9 голосов
/ 10 марта 2009

instanceof всегда возвращает false для null. Он не компилируется, если это будет невозможно, поскольку статический тип слева не может быть экземпляром указанного типа. Кроме этого, он должен работать без удивления.

В отличие от C ++ (и я считаю, Smalltalk), объект не может изменить тип во время выполнения. В C ++ тип изменяется во время конструирования, поэтому методы нельзя вызывать из конструктора для методов производного класса [подкласса].

5 голосов
/ 10 марта 2009

Единственное, что я знаю, это то, что null это instanceof нет типа.

3 голосов
/ 10 марта 2009

Пока у вас нет проблем с загрузкой классов, instanceof работает согласованно. Я полагаю, вы знаете, что instanceof B возвращает true, если A наследуется от B, или некоторые из интерфейсов, которые реализует A или расширяет классы A, являются instanceof B.

Если вы получаете false, когда ожидаете true, вы, вероятно, пытаетесь сравнить экземпляры, поступающие из разных ClassLoaders.

0 голосов
/ 10 марта 2009

Возможно, вы хотите использовать isAssignable вместо instanceof:

if (MyInterface.isAssignableFrom(myObject.getClass())) {
  //  do work here
}

Это вернет true для классов, которые реализуют ваш интерфейс.

...