instanceof считают плохой практикой? Если так, при каких обстоятельствах instanceof все еще предпочтителен?

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

Я действительно однако вижу его тут и там в библиотеках Java, таким образом, я предполагаю, что это имеет свое место? При каких обстоятельствах это предпочтительно? Это когда-либо неизбежно?

62
задан BalusC 11 August 2010 в 00:51
поделиться

6 ответов

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

То же самое в части поддержки устаревшего кода, когда вы не можете внедрить какое-то новое поведение во множество старых классов только для того, чтобы добавить новую небольшую функцию или исправление ошибки ...

11
ответ дан 24 November 2019 в 16:54
поделиться

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

if (o instanceof MyThing) {
    ((MyThing) o).doSomething(); // This is now guaranteed to work.
} else {
    // Do something else, but don't crash onto ClassCast- or NullPointerException.
}
1
ответ дан 24 November 2019 в 16:54
поделиться

Это определенно имеет место в стандартной реализации равно . Например.

public boolean equals ( Object o )
{
  if ( this == o )
  {
     return true;
  }

  if ( ! (o instanceof MyClass) )
  {
    return false;
  }

  // Compare fields
  ...
}

Что важно знать о instanceof, так это то, что его LHS может иметь значение null , и в этом случае выражение оценивается как false .

22
ответ дан 24 November 2019 в 16:54
поделиться

Я согласен, что это может иметь плохой запах. Много instanceof, особенно в цепочке if блока, дурно пахнет.

Иногда он может вести себя так, как вы не ожидаете... Однажды у меня случилось следующее:

Class B extends A
Class C extends A

B b = new B();
C c = new C();

b instanceof B -> true
b instanceof C -> true
c instanceof C -> true
c instanceof B -> true

(в моем случае это произошло из-за того, что hibernate сделал прокси-объекты...., но это просто случай, когда код, зависящий от instanceof, рискован)

2
ответ дан 24 November 2019 в 16:54
поделиться

Когда вы находитесь внутри чисто объектно-ориентированной модели, тогда instanceof определенно является запахом кода.

Если, однако, вы не используете 100% объектно-ориентированную модель или вам нужно внедрить в нее что-то извне, тогда instanceof или его эквиваленты ( isXXX () , getType () , ...) может иметь свое применение.

Общее «правило» - избегать этого, когда это возможно, особенно когда вы управляете иерархией типов и можете использовать, например, полиморфизм подтипов. Идея состоит не в том, чтобы спросить объект, что это за тип и что-то с ним сделать, а в том, чтобы прямо или косвенно попросить объект через посетителя (по сути, двойной полиморфизм) выполнить какое-либо действие.

5
ответ дан 24 November 2019 в 16:54
поделиться

Я думаю, что когда вам абсолютно необходимо знать тип объекта, instanceof является лучшим вариантом.

Плохой практикой было бы иметь много instanceofов, один рядом с другим, и в соответствии с ними вызывать различные методы объектов (конечно, с кастингом). Это, вероятно, отразит, что иерархия нуждается в переосмыслении и, возможно, в рефакторинге.

13
ответ дан 24 November 2019 в 16:54
поделиться
Другие вопросы по тегам:

Похожие вопросы: