ClassCastException vs instanceOf в универсальных коллекциях
У меня есть класс, который реализует Collection<E>.
Когда я проверяю, содержит ли моя коллекция элемент, метод интерфейса дает параметр объекта, когда он должен быть <E>
Как вы думаете, это" нормально", чтобы написать этот код:
@Override
public boolean contains(Object o)
{
E item;
try
{
item=(E) o;
}
catch (ClassCastException e)
{
return false;
}
//check if contains "item"
}
Я знаю, что обычно это ужасная идея-проверять тип объекта с помощью try,catch, но в универсальной коллекции я не могу проверить с помощью instanceOf, и я не нахожу лучшего решения.4 ответа:
Из javadoc он говорит:
Throws: ClassCastException-если тип указанного элемента несовместим с этой коллекцией (необязательно)
Поэтому вполне допустимо закодировать его следующим образом:
@Override public boolean contains(Object o) { T item = (T) o; // ... }И если бросок не удается, бросается
ClassCastException.Вы, конечно, должны не скрывать это исключение и тихо возвращать
false- это может оставить много потенциальных ошибок в коде пользователя.
Если ваш класс коллекции имеет
Eв качестве параметра универсального типа без границ, ваша проверка бесполезна - приведение не может завершиться ошибкой, потому что приведение полностью не проверено.E, если он неограничен, стирается доObject, и ваш бросок будетitem=(Object) o;, который не может потерпеть неудачу. Это может привести к другим неудачам в других местах вниз по линии, но он не может потерпеть неудачу здесь, и если он потерпит неудачу в других местах позже, ваш try-catch не поймает его.Тот факт, что вы не можете использовать
instanceofдолжен я вам кое-что сказал-Причина, по которойinstanceofнельзя использовать, заключается в том, что это проверка во время выполнения, для проверки которой нужен класс во время выполнения, а у вас нет класса во время выполнения. Попытка получить сбой приведения также является проверкой во время выполнения, поэтому она не улучшает вашу ситуацию вообще. Полагаться на то, что приведение к неудаче работает только в тех же ситуациях, что иinstanceof, поэтому никогда не имеет смысла "использовать приведение, потому чтоinstanceofне работает".При написании универсального кода важно: рассмотрим, как выглядит код после стирания типа. Когда вы стираете универсальный код в неродовой код (добавляя приведения в соответствующих местах), код должен работать одинаково. Если невозможно написать код как неродовой, то он также не может быть написан как универсальный.
@Override public boolean contains(Object o) { Object item; try { item= o; } catch (ClassCastException e) // does this make sense? { return false; } //check if contains "item" }