@Sneaky投掷在龙目岛中的应用

我正在用Java玩龙目岛库,发现了一个名为@SneakyThrows的注释。如文档所述:

@SneakyThrows伪造了编译器。换句话说,Lombok 不会包装或替换抛出的已检查异常,而是使编译器认为这是一个未经检查的异常。

换句话说,这是一种在编译时绕过异常的方法。但在我看来,这不应该是处理异常的正确方法,因为绕过的异常可能会在运行时显示奇怪的行为。

那么,在哪种情况下应该使用@SneakyThrows呢?


答案 1

添加到现有答案中。我个人不喜欢检查异常。有关详细信息,请参阅: 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的应用使代码更加清晰。


答案 2

我相信这里的目的是使编译器不需要将任何异常添加到方法声明中。

例如,如果该方法是

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 中,您需要使用龙目岛插件。