Безопасность типов: непроверенное приведение из класса к классу - PullRequest
0 голосов
/ 27 мая 2020

Я создаю функцию, в которой хочу зарегистрировать исключения другого типа во внешней библиотеке. У них уже есть метод, который принимает класс в качестве параметра.

Я хочу прочитать другое исключение из конфигурации и зарегистрировать его, однако я получаю предупреждение о приведении типа. Я могу игнорировать / подавлять его, но есть ли способ не подавить его?

Точное предупреждение: Type safety: Unchecked cast from Class<capture#2-of ?> to Class<? extends Throwable>

Вот пример кода, который выдает предупреждение

Class<?> exceptionClass = Class.forName("java.lang.Exception"); //Getting this value from Config. Let us assume that config is good and I get only valid classname which extends Throwable
registerExceptionInExternalLibrary((Class<? extends Throwable>)exceptionClass); // Getting the warning here

Думаю, я не могу делать здесь кастинг, так как нет объекта. Но если я не использую кастинг, то получаю это предупреждение

The method registerExceptionInExternalLibrary(Class<? extends Throwable>) in the type XXXXX is not applicable for the arguments (Class<capture#2-of ?>)

Вот пример кода

Class<?> exceptionClass = Class.forName("java.lang.Exception"); //Getting this value from Config. Let us assume that config is good and I get only valid classname which extends Throwable
registerExceptionInExternalLibrary(exceptionClass); // Getting the warning here

Ответы [ 2 ]

3 голосов
/ 27 мая 2020

Вы можете использовать Class.asSubClass для этого.

Class<?> exceptionClass = Class.forName("java.lang.Exception");
registerExceptionInExternalLibrary(exceptionClass.asSubclass(Throwable.class));

Полный код метода выглядит следующим образом и показывает, что вы просто выгружаете приведение (и подавление предупреждений) в метод JDK, так что в этом нет ничего особенного. Но это очень удобно в цепочках map(), да и здесь хорошо работает. Также он проверяет, что вы выполняете правильное приведение с помощью isAssignableFrom, что является дополнительной функцией, которую вы бы забыли написать, если бы вы только что выполнили приведение самостоятельно и подавили предупреждение.

@SuppressWarnings("unchecked")
public <U> Class<? extends U> asSubclass(Class<U> clazz) {
    if (clazz.isAssignableFrom(this))
        return (Class<? extends U>) this;
    else
        throw new ClassCastException(this.toString());
}
0 голосов
/ 27 мая 2020

Там есть аналогичный вопрос о непроверенных приведениях.

Короче говоря, компилятор не может быть уверен, что exceptionClass является переменной типа Class<? extends Throwable>, поэтому вы будете в любом случае получите предупреждение.

Вы можете использовать аннотацию @SuppressWarnings с ограниченным объемом:

@SuppressWarnings("unchecked")
Class<? extends Throwable> exceptionClass = (Class<? extends Throwable>)Class.forName("java.lang.Exception");

Приведенная здесь аннотация не повлияет на весь метод.

...