使用jOOλ偷偷摸摸的拋物來避免檢查的異常(附例項)

語言: CN / TW / HK

你不討厭你必須用靜態初始化器來包裝檢查異常的程式碼嗎?例如,你不能在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