java: комбинированный instanceof и cast?

(Пожалуйста, не советуйте мне еще абстрагировать X и добавить к нему еще один метод.)

В C ++, когда у меня есть переменная x из введите X * , и я хочу сделать что-то конкретное, если оно также относится к типу Y * ( Y является подклассом X ) , Я пишу это:

if(Y* y = dynamic_cast(x)) {
    // now do sth with y
}

То же самое кажется невозможным в Java (или это так?).

Вместо этого я прочитал этот код Java:

if(x instanceof Y) {
    Y y = (Y) x;
    // ...
}

Иногда, когда вы не t имеет переменную x , но вместо этого это более сложное выражение, именно из-за этой проблемы вам нужна фиктивная переменная в Java:

X x = something();
if(x instanceof Y) {
    Y y = (Y) x;
    // ...
}
// x not needed here anymore

(Обычное дело, что something () - это iterator.next () . И здесь вы видите, что вы также не можете вызвать это дважды. Вам действительно нужна фиктивная переменная.)

Вам действительно не нужно x здесь вообще - он у вас просто потому, что вы не можете выполнить проверку instanceof сразу с приведением. Сравните это снова с довольно распространенным кодом C ++:

if(Y* y = dynamic_cast( something() )) {
    // ...
}

Из-за этого я ввел функцию castOrNull , которая позволяет избежать фиктивной переменной x . Теперь я могу написать следующее:

Y y = castOrNull( something(), Y.class );
if(y != null) {
    // ...
}

Реализация castOrNull :

public static  T castOrNull(Object obj, Class clazz) {
    try {
        return clazz.cast(obj);
    } catch (ClassCastException exc) {
        return null;
    }
}

Теперь, Мне сказали, что использование этой функции castOrNull таким образом - зло для . Это почему? (Или, чтобы задать более общий вопрос: согласны ли вы и также считаете, что это зло? Если да, то почему? Или вы думаете, что это допустимый (может быть, редкий) вариант использования?)


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

  1. Иногда я попадаю в ситуацию, когда мне приходится выбирать между добавлением еще одного нового метода для очень конкретной вещи (который будет применяться только для одного отдельного подкласса в одном конкретном случае) или используя такой instanceof check. По сути, у меня есть выбор между добавлением функции doSomethingVeryVerySpecificIfIAmY () или выполнением проверки instanceof . И в таких случаях Я считаю, что последний более чистый.

  2. Иногда у меня есть коллекция некоторого интерфейса / базового класса, и для всех записей типа Y я хочу что-то сделать, а затем удалить их из коллекции. (Например, у меня был случай, когда у меня была древовидная структура, и я хотел удалить все дочерние элементы, которые являются пустыми листьями.)

6
задан Community 23 May 2017 в 10:30
поделиться