diff --git a/hutool-core/src/main/java/cn/hutool/core/exceptions/CheckedUtil.java b/hutool-core/src/main/java/cn/hutool/core/exceptions/CheckedUtil.java new file mode 100644 index 000000000..2d4170b0c --- /dev/null +++ b/hutool-core/src/main/java/cn/hutool/core/exceptions/CheckedUtil.java @@ -0,0 +1,328 @@ +package cn.hutool.core.exceptions; + +import java.util.Objects; +import java.util.function.*; + +/** + * 方便的执行会抛出受检查类型异常的方法调用或者代码段 + *

+ * 该工具通过函数式的方式将那些需要抛出受检查异常的表达式或者代码段转化成一个标准的java8 functional 对象 + *

+ * + *
+ *      //代码中如果遇到一个方法调用声明了受检查异常那么我们的代码就必须这样写
+ *         Map describedObject = null;
+ *         try {
+ *             describe = BeanUtils.describe(new Object());
+ *         } catch (IllegalAccessException e) {
+ *             throw new RuntimeException(e);
+ *         } catch (InvocationTargetException e) {
+ *             throw new RuntimeException(e);
+ *         } catch (NoSuchMethodException e) {
+ *             throw new RuntimeException(e);
+ *         }
+ *         // use describedObject ...
+ *
+ *       //上面的代码增加了异常块使得代码不那么流畅,现在可以这样写:
+ *       Map describedObject = CheckedUtil.uncheck(BeanUtils::describe).apply(new Object());
+ *       // use describedObject ...
+ *
+ *       CheckedUtil.uncheck 方法接受任意可以转化成标准java8 函数式接口的 Lambda 表达式。返回对应的函数式对象。
+ *       上述代码可以理解为:
+ *        Function> aFunc = CheckedUtil.uncheck(BeanUtils::describe);
+ *        Map describedObject = aFunc.apply(传入参数);
+ *        该aFunc对象代表的就是BeanUtils::describe这个表达式,且在内部转化了检查类型异常,不需要代码里面显示处理。
+ *
+ *
+ * 
+ * + * @author conder + */ +public class CheckedUtil { + + /** + * 接收一个可以转化成 java.util.function.Function的Lambda表达式,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param 运行时传入的参数类型 + * @param 最终返回的数据类型 + * @return java.util.function.Function + */ + public static Function uncheck(MorFunction expression) { + return uncheck(expression, new RuntimeException()); + } + + /** + * 接收一个可以转化成 java.util.function.BiFunction的Lambda表达式当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param 运行时传入的参数类型一 + * @param 运行时传入的参数类型二 + * @param 最终返回的数据类型 + * @return java.util.function.BiFunction + */ + public static BiFunction uncheck(BiFunction expression) { + return uncheck(expression, new RuntimeException()); + } + + /** + * 接收一个可以转化成 java.util.function.Consumer的Lambda表达式,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param 运行时传入的参数类型 + * @return java.util.function.Consumer + */ + public static Consumer uncheck(MorConsumer expression) { + return uncheck(expression, new RuntimeException()); + } + + /** + * 接收一个可以转化成 java.util.function.BiConsumer的Lambda表达式,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param 运行时传入的参数类型一 + * @param 运行时传入的参数类型二 + * @return java.util.function.BiConsumer + */ + public static BiConsumer uncheck(MorBiConsumer expression) { + return uncheck(expression, new RuntimeException()); + } + + /** + * 接收一个可以转化成 java.util.function.Runnable的Lambda表达式,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @return java.util.function.Runnable + */ + public static Runnable uncheck(MorRunnable expression) { + return uncheck(expression, new RuntimeException()); + } + + /** + * 接收一个可以转化成 java.util.function.Supplier的Lambda表达式,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param 运行时传入的参数类型 + * @return java.util.function.Supplier + */ + public static Supplier uncheck(MorSupplier expression) { + return uncheck(expression, new RuntimeException()); + } + + + /** + * 接收一个可以转化成 java.util.function.Function的Lambda表达式,和一个RuntimeException,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param rte 期望抛出的运行时异常 + * @param 运行时传入的参数类型 + * @param 最终返回的数据类型 + * @return java.util.function.Function + */ + public static Function uncheck(MorFunction expression, RuntimeException rte) { + Objects.requireNonNull(expression, "expression can not be null"); + return t -> { + try { + return expression.apply(t); + } catch (Throwable throwable) { + if (rte == null) { + throw new RuntimeException(throwable); + } else { + rte.initCause(throwable); + throw rte; + } + } + }; + } + + /** + * 接收一个可以转化成 java.util.function.BiFunction的Lambda表达式,和一个RuntimeException,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param rte 期望抛出的运行时异常 + * @param 运行时传入的参数类型一 + * @param 运行时传入的参数类型二 + * @param 最终返回的数据类型 + * @return java.util.function.BiFunction + */ + public static BiFunction uncheck(BiFunction expression, RuntimeException rte) { + Objects.requireNonNull(expression, "expression can not be null"); + return (t1, t2) -> { + try { + return expression.apply(t1, t2); + } catch (Throwable throwable) { + if (rte == null) { + throw new RuntimeException(throwable); + } else { + rte.initCause(throwable); + throw rte; + } + } + }; + } + + /** + * 接收一个可以转化成 java.util.function.Consumer的Lambda表达式,和一个RuntimeException,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param rte 期望抛出的运行时异常 + * @param 运行时传入的参数类型 + * @return java.util.function.Consumer + */ + public static Consumer uncheck(MorConsumer expression, RuntimeException rte) { + Objects.requireNonNull(expression, "expression can not be null"); + return t -> { + try { + expression.apply(t); + } catch (Throwable throwable) { + if (rte == null) { + throw new RuntimeException(throwable); + } else { + rte.initCause(throwable); + throw rte; + } + } + }; + } + + /** + * 接收一个可以转化成 java.util.function.BiConsumer的Lambda表达式,和一个RuntimeException,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param rte 期望抛出的运行时异常 + * @param 运行时传入的参数类型一 + * @param 运行时传入的参数类型二 + * @return java.util.function.BiConsumer + */ + public static BiConsumer uncheck(MorBiConsumer expression, RuntimeException rte) { + Objects.requireNonNull(expression, "expression can not be null"); + return (t, u) -> { + try { + expression.apply(t, u); + } catch (Throwable throwable) { + if (rte == null) { + throw new RuntimeException(throwable); + } else { + rte.initCause(throwable); + throw rte; + } + } + }; + } + + /** + * 接收一个可以转化成 java.util.function.Runnable的Lambda表达式,和一个RuntimeException,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param rte 期望抛出的运行时异常 + * @return java.util.function.Runnable + */ + public static Runnable uncheck(MorRunnable expression, RuntimeException rte) { + Objects.requireNonNull(expression, "expression can not be null"); + return () -> { + try { + expression.apply(); + } catch (Throwable throwable) { + if (rte == null) { + throw new RuntimeException(throwable); + } else { + rte.initCause(throwable); + throw rte; + } + } + }; + } + + /** + * 接收一个可以转化成 java.util.function.Supplier的Lambda表达式,和一个RuntimeException,当执行表达式抛出任何异常的时候,都会转化成运行时异常 + * 如此一来,代码中就不用显示的try-catch转化成运行时异常 + * + * @param expression Lambda表达式 + * @param rte 期望抛出的运行时异常 + * @param 运行时传入的参数类型 + * @return java.util.function.Supplier + */ + public static Supplier uncheck(MorSupplier expression, RuntimeException rte) { + Objects.requireNonNull(expression, "expression can not be null"); + return () -> { + try { + return expression.apply(); + } catch (Throwable throwable) { + if (rte == null) { + throw new RuntimeException(throwable); + } else { + rte.initCause(throwable); + throw rte; + } + } + }; + } + + + /** + * 对应java8 java.util.function.Function ,能够接受受检查异常的转化 + * + * @param + * @param + */ + public interface MorFunction { + R apply(T t) throws Throwable; + } + + /** + * 对应java8 java.util.function.BiFunction ,能够接受受检查异常的转化 + * + * @param + * @param + * @param + */ + public interface MorBiFunction { + R apply(T1 t1, T2 t2) throws Throwable; + } + + /** + * 对应java8 java.util.function.Consumer ,能够接受受检查异常的转化 + * + * @param + */ + public interface MorConsumer { + void apply(T t) throws Throwable; + } + + /** + * 对应java8 java.util.function.BiConsumer ,能够接受受检查异常的转化 + * + * @param + * @param + */ + public interface MorBiConsumer { + void apply(T t, U u) throws Throwable; + } + + /** + * 对应java8 java.util.function.Runnable ,能够接受受检查异常的转化 + */ + public interface MorRunnable { + void apply() throws Throwable; + } + + /** + * 对应java8 java.util.function.Supplier ,能够接受受检查异常的转化 + * + * @param + */ + public interface MorSupplier { + R apply() throws Throwable; + } +} diff --git a/hutool-core/src/test/java/cn/hutool/core/exceptions/CheckedUtilTest.java b/hutool-core/src/test/java/cn/hutool/core/exceptions/CheckedUtilTest.java new file mode 100644 index 000000000..fc62d4bf5 --- /dev/null +++ b/hutool-core/src/test/java/cn/hutool/core/exceptions/CheckedUtilTest.java @@ -0,0 +1,53 @@ +package cn.hutool.core.exceptions; + +import org.junit.Assert; +import org.junit.Test; + +import java.io.File; +import java.io.FileInputStream; + +/** + * 方便的执行会抛出受检查类型异常的方法调用或者代码段 + *

+ * 该工具通过函数式的方式将那些需要抛出受检查异常的表达式或者代码段转化成一个标准的java8 functional 对象 + *

+ * + * @author conder + */ +public class CheckedUtilTest { + + + @Test + public void supplierTest() { + File noFile = new File("./no-file"); + try { + //本行代码原本需要抛出受检查异常,现在只抛出运行时异常 + FileInputStream stream = CheckedUtil.uncheck(() -> new FileInputStream(noFile)).get(); + } catch (Exception re) { + Assert.assertTrue(re instanceof RuntimeException); + } + + } + + @Test + public void functionTest() { + CheckedUtil.MorFunction afunc = (funcParam) -> { + if (funcParam.length() > 5) { + throw new Exception("这是受检查异常需要屌用处显示处理"); + } + return funcParam.toUpperCase(); + }; + + //afunc.apply("hello world"); 直接调用需要处理异常 + + + try { + //本行代码原本需要抛出受检查异常,现在只抛出运行时异常 + String reslut = CheckedUtil.uncheck(afunc).apply("hello world"); + } catch (Exception re) { + Assert.assertTrue(re instanceof RuntimeException); + } + + } + +}