Синтаксис java @SuppressWarnings("unchecked") с наследованием универсальных типов

У меня есть классы, определенные следующим образом с некоторыми методами в них

public abstract class Pojo<T extends Pojo<T, U>, U extends Phase<U>> {
    ...
    public T updatePhase(U phase) {
        this.previousPhase = this.phase;
        this.phase = phase;
        return getThis();
    }

    public U getPreviousPhase(U phase) {
        return this.previousPhase;
    }

    @SuppressWarnings("unchecked")
    public T getThis() {
        return (T) this;
    }

    public Map<String, String> getMap() {
        return this.map;
    }
}

public interface Phase<U extends Phase<U>> { ... }

Где-то позже в моем коде я пытаюсь сделать следующее:

Pojo pojo = someService.get(id); // This can't be a definite type since I get this by deserializing a string
Phase ap = pojo.getPreviousPhase();
pojo.updatePhase(ap); // I get the unchecked warning here (case 1)
Map<String, String> myMap = pojo.getMap(); // I get the unchecked warning here (case 2)
myMap.put("1", "2"); // This obviously works

Случай 1: непроверенный вызов updatePhase(U) как член необработанного типа.
Я понимаю, почему это дает предупреждение. Как я могу использовать @SuppressWarnings("unchecked") аннотации в этом случае (по синтаксису)? Как это будет использоваться, если я объединю это в одно утверждение? pojo.updatePhase(pojo.getPreviousPhase)

Случай 2: необязательное преобразование, требуется Map<String,String>, найденный Map
Почему это дает предупреждение? Я возвращаю определенный тип Map<String, String> так что это не должно волновать... Точно так же, как я могу применить @SuppressWarnings аннотации здесь? Точно так же, как я сделал бы это в однострочном выражении pojo.getMap().put("1", "2")

Примечание. Я проверяю в своем коде, что все эти преобразования типов верны и не вызовут ошибок приведения во время выполнения.

1 ответ

Решение

Использование необработанных типов для отключения общей проверки типов - плохая идея. Для первой проблемы, вместо того, чтобы пытаться заставить объект неизвестного типа в универсальный параметр метода неизвестного типа, вы должны сказать Pojo передать себе значение поля внутри:

public T updateFromPrevious() {
    return updatePhase(getPreviousPhase());
}

Как только вы перестанете использовать необработанные типы, компилятор перестанет игнорировать универсальные типы в этих строках, и второе предупреждение исчезнет:

Pojo<?,?> pojo = someService.get(id);
pojo.updateFromPrevious();
Map<String, String> myMap = pojo.getMap();
myMap.put("1", "2");
Другие вопросы по тегам