ПОЧЕМУ нужно использовать оператор instanceof?

Я пытаюсь ответить на этот короткий вопрос, но мне трудно понять, что мой инструктор имеет в виду под «зачем нам это знать?». Любые советы высоко ценится.

Вопрос:

«Какая польза от оператора instanceof? Очевидно, что он будет обозначать, является ли это «экземпляром» чего-то — это не ответ. Вопрос в том, зачем нам это знать?»


person Pat Moloney    schedule 24.02.2013    source источник
comment
А, потому что мы не знаем, что это за объект?   -  person Hot Licks    schedule 24.02.2013
comment
возможный дубликат Когда использование instanceof является правильным решением?   -  person Louis Wasserman    schedule 24.02.2013


Ответы (5)


Наиболее очевидным и очень распространенным (неправильным) использованием оператора instanceof является выбор специальной обработки для подкласса:

void recordPayment(Payment pmt) {
    // Do something common for all subclasses
    recordAmount(pmt.getAmount());
    // Do something special for the credit card subclasses
    if (pmt instanceof CreditCardPayment) {
        CreditCardPayment ccPmt = (CreditCardPayment)pmt;
        recordCreditCardNumber(ccPmt.getCardNumber());
    }
}

Использование instanceof часто почти наверняка указывает на то, что в вашем проекте отсутствует функция в базовом классе и переопределение в производном классе.

person Sergey Kalinichenko    schedule 24.02.2013

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

Таким образом, instanceof используется, чтобы разобраться с этим или, по крайней мере, убедиться, что ожидаемый тип присутствует, а не пытаться выполнить приведение и взорвать.

person Hot Licks    schedule 24.02.2013

Если кто-то хочет привести вниз тип, ему может понадобиться оператор instanceof. Но это обычно указывает на запахи кода.

Вы можете обратиться к этой статье: "Предпочитайте полиморфизм, а не instanceof и понижающее приведение".

ОБНОВЛЕНИЕ:

Кажется, ОП не понимает смысла понижения, давайте объясним подробнее.

Понижающее приведение уточняет/сужает видимый тип объекта/значения до одного из его подтипов, чтобы он имел семантику подтипа.

Это полезно, когда объект/значение объявлено как его супертип, но вызывающему объекту нужна некоторая семантика или интерфейсы, которые конкретно принадлежат подтипу (т. е. те, которые отсутствуют< /em> в супертипе). Только после того, как объект/значение пройдет тест instanceof и будет понижен до этого подтипа, вызывающий объект может использовать его конкретную семантику или интерфейсы.

person Hui Zheng    schedule 24.02.2013
comment
1+ за упоминание запахов кода - это оператор, который вы хотите использовать очень экономно, если вообще. - person Hovercraft Full Of Eels; 24.02.2013
comment
@HotLicks, почему? Вы видели, что я сказал обычно пахнет? - person Hui Zheng; 24.02.2013
comment
Высказывание обычно указывает на то, что либо вы читали много действительно паршивого кода, либо вы очень плохо разбираетесь в хорошем коде. Я позволю вам решить, какой. - person Hot Licks; 24.02.2013
comment
@HotLicks хорошо, эта статья Downcasting - это запах кода (codebetter.com/jeremymiller/2006/12/26/) даже опускает слово обычно. - person Hui Zheng; 24.02.2013
comment
Я занимаюсь программированием уже 40 лет, и до прошлой недели я никогда не слышал слово «код пахнет». Это изобретение какого-то нового, самопровозглашенного эксперта, а не термин искусства. Я бы не стал доверять пользователю этого термина, поскольку я мог бы бросить его (что не так уж и далеко с этим задним плечом). - person Hot Licks; 24.02.2013
comment
@HotLicks Это всего лишь ваше личное мнение. Пожалуйста, взгляните на вики: en.wikipedia.org/wiki/Code_smell - person Hui Zheng; 24.02.2013
comment
Я не вижу instanceof в этом списке. - person Hot Licks; 24.02.2013

Зависит от того, что вам нужно. Я почти всегда использую «экземпляр», например, когда работаю с переменными типа «Объект» и т. д.

Простая вещь — использование объектов разных типов в массиве. Например:

Object[] data = new Object[4];

data[0] = "String";
data[1] = 32;
data[2] = 32.64D;
data[3] = new ArrayList<String>();

Затем вы можете проверить содержимое:

if (data[0] instanceof String) {
  // Content at index '0' is a String
}
person JoaaoVerona    schedule 24.02.2013
comment
но вопрос ЗАЧЕМ. В вопросе уже указано, для чего он используется, но это то, что я пытаюсь выяснить: вопрос в том, зачем нам это знать? - person Pat Moloney; 24.02.2013
comment
@PatMoloney Потому что иногда вам приходится писать методы, которые работают с чем-то общим (например, Object), но вам нужно делать что-то другое, если объект является чем-то конкретным (например, String). Не всегда можно заранее узнать, какого типа данные будут. - person Brian Rogers; 24.02.2013

Возьмем такую ​​ситуацию: у вас есть ссылка superclass, которая может ссылаться на любой из экземпляров производного класса.
Например, существует класс abstract Clothes. Три класса Shirt, Shorts и Jeans являются производными от него.

Clothes coolshirt=new Shirt();
Clothes coolshorts=new Shorts();
Clothes cooljeans=new Jeans();
Clothes gift=receiveGift();
if(gift instanceof Shirt)//Is the gift refers to a instance of Shirt
sendGratitude("Thanks for your new Shirt. It is really cool");
else if(gift instanceof Shorts)//Is the gift refers to a instance of Shorts
sendGratitude("Your shorts fits nice for me.Thank you.");
else if(gift instanceof Jeans)//Is the gift refers to a instance of Jeans
sendGratitude("In your Jeans I really look, Handsome, Very Thanks");
person Govind Balaji    schedule 24.02.2013