Преобразование 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")
), который бы достигал этого для всех классов со структурой, аналогичной показанной выше, т.е. мне пришлось бы написать вспомогательный метод для каждого такого класса, что противоречит второму требованию.
Я предполагаю, что для решения потребуется некоторая форма генерации кода (например, с помощью процессора аннотаций), который автоматически генерирует необходимые вспомогательные методы, выполняющие безопасные преобразования. Есть ли что-нибудь подобное?