- 1 异常引入
- 2 @SneakyThrows
- 1 SneakyThrows注解的源码
- 2使用案例
1 异常引入关于@SneakyThrows注解的使用,主要是消除代码中异常处理代码.
Java中异常Throwable分为两类, 一种是Exception类,称为受检异常(Checked Exception), 第二种是RuntimeException类, 运行时异常.
Exception类异常,强制要求方法抛出可能出现的异常,调用者必须处理这个异常. 一般在代码中,程序员通过捕获异常,再包一层RuntimeException,向外抛出.(常见如Spring源码中)
2 @SneakyThrows 1 SneakyThrows注解的源码@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.SOURCE)
public @interface SneakyThrows {
Class extends Throwable>[] value() default java.lang.Throwable.class;
//The fully qualified name is used for java.lang.Throwable in the parameter only. This works around a bug in javac:
// presence of an annotation processor throws off the type resolver for some reason.
}
2使用案例
public class SneakyThrowDemo {
// 方法主动声明可能出现的异常
public void test1() throws IllegalAccessException, InstantiationException {
SneakyThrowDemo sneakyThrowDemo = SneakyThrowDemo.class.newInstance();
}
// 使用SneakyThrows注解
@SneakyThrows
public void test2() {
SneakyThrowDemo sneakyThrowDemo = SneakyThrowDemo.class.newInstance();
}
// test2方法的编译结果
public void test3() {
try {
SneakyThrowDemo sneakyThrowDemo = SneakyThrowDemo.class.newInstance();
} catch (Throwable e) {
// 调用Lombok方法转化为RuntimeException
throw Lombok.sneakyThrow(e);
}
}
}
其中Lombok.sneakyThrow()方法
public static RuntimeException sneakyThrow(Throwable t) {
if (t == null) throw new NullPointerException("t");
return Lombok.sneakyThrow0(t);
}
// 对返回参数做了强转为T类型
private static T sneakyThrow0(Throwable t) throws T {
throw (T)t;
}
整个处理过程中, 最重要的是throw (T)t, 使用泛型,将传入的Throwable强转为RuntimeException异常.
虽然, 我们抛出的异常不是RuntimeException,但是可以骗过javac编译器,泛型最后存储为字节码文件时并没有泛型信息.



