Java SneakyThrow исключений, стирание типов
Может кто-нибудь объяснить этот код?
public class SneakyThrow {
public static void sneakyThrow(Throwable ex) {
SneakyThrow.sneakyThrowInner(ex);
}
private static T sneakyThrowInner(Throwable ex) throws T {
throw (T) ex;
}
public static void main(String[] args) {
SneakyThrow.sneakyThrow(new Exception());
}
}
Это может показаться странным, но это неt создает исключение приведения и позволяет генерировать проверенное исключение, не объявляя его в подписи, или заключать его в непроверенное исключение.
Обратите внимание, что ниsneakyThrow(...)
или основной объявляет любое проверенное исключение, но вывод:
Exception in thread "main" java.lang.Exception
at com.xxx.SneakyThrow.main(SneakyThrow.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Этот хак используется в Lombok с аннотацией @SneakyThrow, которая позволяет генерировать проверенные исключения, не объявляя их.
Я знаю, что это как-то связано с стиранием типов, но яЯ не уверен, чтобы понять каждую часть взломать.
Редактировать: Я знаю, что мы можем вставитьInteger
вList
и что различие между проверенными / непроверенными исключениями является функцией времени компиляции.
При приведении из неуниверсального типа, такого какList
на общий тип, какList
компилятор выдает предупреждение. Но это'Менее распространено приведение к универсальному типу, например(T) ex
в приведенном выше коде.
Если хотите, то, что мне кажется странным, так это то, что я понимаю, что внутри JVMList
а такжеList
выглядит так же, но приведенный выше код, кажется, означает, что, наконец, мы также можем присвоить значение типа Cat переменной типа Dog или что-то в этом роде.