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

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

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

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

4b9b3361

Ответ 1

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

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

Ответ 2

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

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

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

  // Compare fields
  ...
}

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

Ответ 3

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

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

Ответ 4

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

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

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

Ответ 5

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

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.
}

Ответ 6

Я изучал эту же тему для других целей, и я нашел следующие ссылки действительно хорошими.

Ответ 7

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

Иногда он может вести себя так, как вы этого не ожидали... Что-то, что я однажды произошло:

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

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

Ответ 8

Как насчет в случае создания factory? например.

public static Cage createCage(Animal animal) {
  if (animal instanceof Dog)
    return new DogHouse();
  else if (animal instanceof Lion)
    return new SteelCage();
  else if (animal instanceof Chicken)
    return new ChickenWiredCage();
  else if (animal instanceof AlienPreditor)
    return new ForceFieldCage();
  ...
  else
    return new GenericCage();
}