使用jOOλ偷偷摸摸的抛物来避免检查的异常(附实例)

你不讨厌你必须用静态初始化器来包装检查异常的代码吗?例如,你不能在Java中这样写:

public class Test {
    static final Class<?> klass = Class.forName("org.h2.Driver");
}

有一个未处理的ClassNotFoundException ,你不能简单地捕捉/重新抛出它。需要一个静态初始化器:

public class Test {
    static final Class<?> klass;

    static {
        try {
            klass = Class.forName("org.h2.Driver");
        }
        catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
}

幸运的是,jOOλ的 一个不太为人所知的功能是 [Sneaky](https://www.jooq.org/products/jOO%CE%BB/javadoc/latest/org/jooq/lambda/Sneaky.html)类,它包含了一堆实用的方法,可以将JDK的功能接口包装成一个等价的、"偷偷抛出 "的功能接口,不需要声明被检查的异常。

简而言之,你可以这样写:

public class Test {
    static final Class<?> klass = Sneaky.supplier(
        () -> Class.forName("org.h2.Driver")
    ).get();
}

异常被 "偷偷 "地重新抛出,因为JVM并不关心一个异常的检查性。如果你的classpath上没有H2,你会得到:

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.ClassNotFoundException: org.h2.Driver
	at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
	at java.base/java.lang.Class.forName0(Native Method)
	at java.base/java.lang.Class.forName(Class.java:375)
	at org.jooq.test.util.Test.lambda$0(Test.java:44)
	at org.jooq.lambda.Unchecked.lambda$supplier$38(Unchecked.java:1695)
	at org.jooq.test.util.Test.<clinit>(Test.java:44)

你可以在其他需要JDK功能接口的地方使用这种方法,而且你不关心异常的检查性,例如在流中:

// Doesn't compile:
Stream
    .generate(
        () -> Class.forName("org.h2.Driver"))
    .limit(1)
    .forEach(System.out::println);

// So ugly
Stream
    .generate(
        () -> {
            try {
                return Class.forName("org.h2.Driver");
            }
            catch (ClassNotFoundException e) {
                throw new RuntimeException(e);
            }
        })
    .limit(1)
    .forEach(System.out::println);

// Use jOOλ's Sneaky supplier
Stream
    .generate(Sneaky.supplier(
        () -> Class.forName("org.h2.Driver")))
    .limit(1)
    .forEach(System.out::println);

在这里获取jOOλ:https://github.com/jOOQ/jOOL

猜你喜欢

转载自juejin.im/post/7126362829145243685