Java не проверял приведение к типу предупреждения параметра несмотря на то, что был экземпляром

Считайте, что у вас есть этот список:

private final List<? extends AbstractXmlElement> inMemoryElements;

он содержит группу объектов подклассов AbstractXmlElement, и вы хотите добавить метод для фильтрации объектов определенного подкласса из этого списка. Для этого я создал следующий метод:

public <E extends AbstractXmlElement> List<E> getInstancesOf(Class<E> c) {
    return getUsableElements().stream()
        .filter(c::isInstance)
        .map(e -> (E) e)
        .collect(Collectors.toList());
}

Все же (E) e приводит к Предупреждению UncheckedCast. Мне было интересно, как именно это неконтролируемое приведение и безопасно ли подавлять это предупреждение, так как те объекты, которые не являются экземпляром E, отфильтровываются перед приведением. Это означает, что, насколько я знаю, актерский состав никогда не должен проваливаться.

2 ответа

Решение

Это непроверенный актерский состав, потому что тип E неизвестно во время выполнения. Так как вы проверяете isInstance()Ваш код в безопасности. Но если вы хотите избежать предупреждения, вы можете использовать c сделать актерский состав:

.map(c::cast)

как именно это непроверенный актерский состав

Ваша единственная гарантия в том, что e это пример AbstractXmlElement, Но это может быть любой подкласс. Так что, если у вас был подкласс A а также B оба расширяются AbstractXmlElementтеоретически ограничение типа означает, что вы можете попытаться разыграть A в B, который потерпел бы неудачу, если бы вы прошли B.class в качестве аргумента и ваша коллекция содержала экземпляры A, Отсюда и предупреждение.

Обратите внимание, что компилятор не проверяет выражение фильтра, чтобы выяснить, что только E может когда-нибудь пройти мимо фильтра; в частности, он не идет и читает документацию, а затем также предполагает, что документация верна. Насколько это может сказать, c::isInstance() это просто еще один случайный метод, принимающий Object и возвращая boolean, Там нет ничего, чтобы указать только случаи E оставаться в потоке мимо фильтра.

если это безопасно, чтобы подавить это предупреждение

В этом случае да.

Другие вопросы по тегам