@Sneaky Throws在lombok中的应用
Application of @Sneaky Throws in lombok
我在 Java 中使用 Lombok 库,发现了一个名为 @SneakyThrows 的注解。
正如文档所述:
@SneakyThrows fakes out the compiler. In other words, Lombok doesn't wrap or replace the thrown checked exception, but makes the compiler think that it is an unchecked exception.
换句话说,这是一种在编译时绕过异常的方法。但在我看来这不应该是处理异常的正确方式,因为被绕过的异常会在运行时表现出奇怪的行为。
那么@SneakyThrows应该在什么场景下使用呢?
在 JAVA 8 及更高版本中,使用 lambda 时尤其不容易使用。
- 考虑主要用于旧版本的 Java 8.
- 目的本身就是故意抛出一个异常,比如警告。通过这个,另一个 services/program/code 可以确定应该如何处理 request/response 流。如果你已经有了机制就不用担心了。
@SneakyThrows
在当前的传统应用程序开发中没有多大用处,可以在某些需要(虽然我没有这方面的专业知识)确定状态的状态机程序中使用程序电流。这只是 1 个不同场景的示例,可能还有更多。
我相信这里的目的是使编译器不需要将任何异常添加到方法声明中。
例如,如果方法是
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
这会导致编译时异常需要
public void throwsCheckedException() throws IOException {
throw new IOException("IO exception thrown");
}
注释@SneakThrows 缓解了这种情况 - 原始方法声明为
@SneakyThrows
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
这不会导致编译时错误。
注意 IDE 可能仍会将其突出显示为错误,例如在 IntelliJ 中您将需要使用 Lombok 插件。
添加到现有答案中。我个人不喜欢检查异常。有关详细信息,请参阅:https://phauer.com/2015/checked-exceptions-are-evil/
雪上加霜的是,代码在避免检查异常时会变得臃肿。考虑@SneakyThrows 的用法:
List<Instant> instantsSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(Example::parseSneaky)
.collect(Collectors.toList());
@SneakyThrows
private static Instant parseSneaky(String queryValue) {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
与非@SneakyThrows
private static Instant parseNonSneaky(String queryValue) throws ParseException {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
List<Instant> instantsNonSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(timeStamp -> {
try {
return parseNonSneaky(timeStamp);
} catch (ParseException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
因此@SneakyThrows 的应用使代码更加简洁。
我在 Java 中使用 Lombok 库,发现了一个名为 @SneakyThrows 的注解。 正如文档所述:
@SneakyThrows fakes out the compiler. In other words, Lombok doesn't wrap or replace the thrown checked exception, but makes the compiler think that it is an unchecked exception.
换句话说,这是一种在编译时绕过异常的方法。但在我看来这不应该是处理异常的正确方式,因为被绕过的异常会在运行时表现出奇怪的行为。
那么@SneakyThrows应该在什么场景下使用呢?
在 JAVA 8 及更高版本中,使用 lambda 时尤其不容易使用。
- 考虑主要用于旧版本的 Java 8.
- 目的本身就是故意抛出一个异常,比如警告。通过这个,另一个 services/program/code 可以确定应该如何处理 request/response 流。如果你已经有了机制就不用担心了。
@SneakyThrows
在当前的传统应用程序开发中没有多大用处,可以在某些需要(虽然我没有这方面的专业知识)确定状态的状态机程序中使用程序电流。这只是 1 个不同场景的示例,可能还有更多。
我相信这里的目的是使编译器不需要将任何异常添加到方法声明中。
例如,如果方法是
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
这会导致编译时异常需要
public void throwsCheckedException() throws IOException {
throw new IOException("IO exception thrown");
}
注释@SneakThrows 缓解了这种情况 - 原始方法声明为
@SneakyThrows
public void throwsCheckedException() {
throw new IOException("IO exception thrown");
}
这不会导致编译时错误。 注意 IDE 可能仍会将其突出显示为错误,例如在 IntelliJ 中您将需要使用 Lombok 插件。
添加到现有答案中。我个人不喜欢检查异常。有关详细信息,请参阅:https://phauer.com/2015/checked-exceptions-are-evil/
雪上加霜的是,代码在避免检查异常时会变得臃肿。考虑@SneakyThrows 的用法:
List<Instant> instantsSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(Example::parseSneaky)
.collect(Collectors.toList());
@SneakyThrows
private static Instant parseSneaky(String queryValue) {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
与非@SneakyThrows
private static Instant parseNonSneaky(String queryValue) throws ParseException {
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'").parse(queryValue).toInstant();
}
List<Instant> instantsNonSneaky = List.of("2020-09-28T12:30:08.797481Z")
.stream()
.map(timeStamp -> {
try {
return parseNonSneaky(timeStamp);
} catch (ParseException e) {
throw new RuntimeException(e);
}
})
.collect(Collectors.toList());
因此@SneakyThrows 的应用使代码更加简洁。