Можно доказать, что отказ от @SuppressWarnings ("не отмечен") при применении является безопасным. - PullRequest
3 голосов
/ 28 мая 2020

Преобразование MyClass<?> в MyClass<SomeType> обычно небезопасно и требует аннотирования кода с помощью @SuppressWarnings("unchecked"), чтобы избежать соответствующего предупреждения компилятора. Однако в некоторых случаях легко показать, что гипсовая повязка на самом деле совершенно безопасна. Рассмотрим, например, класс, определенный следующим образом:

public class MyClass<T> {
    private final Class<T> type;

    public MyClass(Class<T> type) {
        this.type = type;
    }

    public Class<T> getType() {
        return type;
    }
}

Предположим, что у меня есть ссылки Class<SomeType> c и MyClass<?> m. Если c != null && m.getType() == c, то экземпляр m может быть создан только как MyClass<SomeType>, т.е. преобразование m в MyClass<SomeType> в этом случае совершенно безопасно. Фактически объект Class действует как «токен типа», который позволяет мне во время выполнения проверять, что такое общий c тип экземпляра MyClass.

Вопрос в том, существует ли метод , инструмент или библиотека, которые позволяют мне писать мой код безопасным способом без необходимости подавлять предупреждения с помощью @SuppressWarnings("unchecked") (для случая, показанного выше, и, возможно, других случаев, когда просто доказать безопасность типа)? Точнее, я ищу решение, отвечающее следующим требованиям:

  • Оно гарантирует безопасность типов, т.е. небезопасные приведения приведут к ошибке / предупреждению во время сборки или во время выполнения, когда приведение попытка.
  • Мне не нужно писать вспомогательный метод для каждого такого случая.
  • Это не позволяет избежать преобразования MyClass<?> в MyClass<SomeType>: в некоторой степени можно безопасно взаимодействовать с экземпляром MyClass без выполнения этого приведения (и вместо этого использовать экземпляр Class, возвращаемый getType() в приведениях), но это не общее решение.

Я почти уверен, что этого невозможно достичь с помощью стандартных языковых функций. Я думаю, что также невозможно написать единственный вспомогательный метод generi c (сам полагающийся на @SuppressWarnings("unchecked")), который бы достигал этого для всех классов со структурой, аналогичной показанной выше, т.е. мне пришлось бы написать вспомогательный метод для каждого такого класса, что противоречит второму требованию.

Я предполагаю, что для решения потребуется некоторая форма генерации кода (например, с помощью процессора аннотаций), который автоматически генерирует необходимые вспомогательные методы, выполняющие безопасные преобразования. Есть ли что-нибудь подобное?

...