├── .gitignore ├── LICENSE ├── README.md ├── pom.xml └── src └── main └── java └── com └── robot └── util └── LambdaExceptionUtil.java /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | src/main/java/com/.DS_Store 25 | .DS_Store 26 | .idea/* 27 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LambdaExceptionThrower 2 | 3 | [![GitHub](https://img.shields.io/github/license/luo-zhan/Transformer)](http://opensource.org/licenses/apache-2-0) 4 | [![GitHub code size in bytes](https://img.shields.io/github/languages/code-size/luo-zhan/LambdaExceptionThrower)]() 5 | [![SolarLint](https://img.shields.io/badge/SolarLint-Perfect-gold)]() 6 | [![GitHub last commit](https://img.shields.io/github/last-commit/luo-zhan/LambdaExceptionThrower?label=Last%20commit)]() 7 | 8 | Java里写Lambda表达式的时候居然必须要try-catch掉内部异常,简直不能忍!😠 9 | 10 | ## 使用说明 11 | 12 | ### 1. lambda方法声明 13 | 14 | ```java 15 | // 编译不通过,未处理异常“MalformedURLException” 16 | Function function=URL::new; 17 | // 使用LambdaExceptionThrower后,编译通过! 18 | Function function=wrapFunction(URL::new); 19 | ``` 20 | ### 2. 看一个更常见的例子 21 | 22 | 如果我们在`Stream`的`map()`方法中使用一个会抛出异常的方法:(此处将一批url字符串转换成URL对象模拟这种场景) 23 | 24 | #### Before: 25 | 26 | ```java 27 | class Test { 28 | 29 | public static void main(String[] args) { 30 | List source = Arrays.asList("http://example1.com", "http://example2.com", "http://example3.com"); 31 | List urlList = source.stream().map(url -> { 32 | // 必须要捕获异常,否则无法编译通过 33 | try { 34 | return new URL(url); 35 | } catch (MalformedURLException e) { 36 | // 抛异常只能抛unchecked-exception(RuntimeException或Error),或者处理掉异常不往上抛。 37 | throw new RuntimeException(e); 38 | } 39 | }).collect(Collectors.toList()); 40 | } 41 | } 42 | ``` 43 | 上面代码中`new URL(url)`会抛出`MalformedURLException`,在lambda表达式中必须被try-catch,无法向上抛出,这样不仅代码累赘,而且在实际开发中,绝大多数的异常都是需要向上抛出的,这样就无法简便的使用Stream API了。 44 | 45 | #### After 46 | 47 | ```java 48 | // 此处静态导入方法 49 | 50 | import static com.robot.util.LambdaExceptionUtil.wrapFunction; 51 | 52 | class Test { 53 | public static void main(String[] args) throws MalformedURLException { // 注意这里增加了异常申明 54 | List source = Arrays.asList("http://example1.com", "http://example2.com", "http://example3.com"); 55 | 56 | // 只需要在原来的lambda表达式外用wrapFunction()方法包裹一下即可,注意异常已经被抛到了上层 57 | List urlList = source.stream() 58 | .map(wrapFunction(url -> new URL(url))) 59 | .collect(Collectors.toList()); 60 | 61 | // 还可以使用方法引入,代码更加简洁! 62 | List urlList1 = source.stream() 63 | .map(wrapFunction(URL::new)) 64 | .collect(Collectors.toList()); 65 | } 66 | } 67 | ``` 68 | 69 | #### Tips 70 | 71 | 1.使用IDEA写代码时可以直接敲`wrapFunction(...)`,然后按`⌥+↩︎`(`Opition+回车`,Windows是`Alt+回车`),选择弹出菜单中的“import 72 | static...”即可快速导入方法 73 | ![快捷静态导入](https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/course/lambda2.png) 74 | 75 | 2.使用`wrapFunction`方法包裹后,idea是会提示未捕获方法异常的,只需要点击一下就自动在方法上申明了异常,和平时写代码异常处理操作无异 76 | ![快捷申明异常](https://msb-edu-dev.oss-cn-beijing.aliyuncs.com/course/lambda.png) 77 | 78 | ## One more thing 79 | 80 | 工具类中还提供了另一个很好用的方法,`sure()`。 81 | 82 | 如果一段代码**确保**不会抛出所申明的异常,可以使用该方法进行包装,此时既不用写try-catch,也不用在方法申明上throw异常,代码相当简洁。 83 | 84 | ```java 85 | import static com.robot.util.LambdaExceptionUtil.sure; 86 | 87 | class Test { 88 | // 如下String的构造方法申明了UnsupportedEncodingException,但编码"UTF-8"是必定不会抛异常的,使用sure(...)进行包装 89 | String text = sure(() -> new String(byteArr, "UTF-8")); 90 | 91 | // 通过class创建对象,而已知此实例化一定不会产生异常 92 | Map map = sure(HashMap.class::newInstance); 93 | 94 | // 反射获取某个类的属性,而已知这个类必然含有该属性 95 | Field field = sure(() -> someClass.getDeclaredField("id")); 96 | 97 | // 测试时用的sleep方法,不必改变测试方法上的异常申明 98 | sure(() ->Thread.sleep(1000)); 99 | } 100 | ``` 101 | 102 | > 注意:sure方法虽然好用,但它也隐藏了可能的异常申明,所以请谨慎使用,确定(sure)一定不会抛出异常! 103 | 104 | ## API 105 | 106 | 有手就会😉 107 | 108 | ```js 109 | // 最常用的4个 110 | wrapFunction(Function);// Function:普通函数(入参出参各一个) 111 | wrapConsumer(Consumer);// Consumer:消费函数(一个入参,没有出参) 112 | wrapSupplier(Supplier);// Supplier:提供函数(没有入参,一个出参) 113 | wrapPredicate(Predicate);// Predicate:条件函数(一个入参,一个出参,且出参类型是boolean) 114 | 115 | // 更多,和jdk8中的函数式接口一一对应 116 | wrapBiFunction(BiFunction); 117 | wrapBiConsumer(BiConsumer); 118 | wrapBiPredicate(BiPredicate); 119 | wrapRunnable(Runnable); 120 | 121 | // 确保不抛出异常时使用 122 | sure(Runnable); 123 | sure(Supplier); 124 | 125 | ``` 126 | 127 | ## Note 128 | 129 | 本工具实现方式是利用泛型的不确定性使得编译器无法区分抛出的异常是uncheck-exception还是check-exception,利用这个漏洞绕开了编译器的检查,所以不会编译报错,然后将异常抛到外层(此时异常还是原来的异常),这和很多解决方案中的把异常转换成RuntimeException抛出的原理是不同的,有兴趣的朋友可以参看源码。 130 | 131 | 思路源自[@MarcG](https://stackoverflow.com/users/3411681/marcg) 132 | 与[@PaoloC](https://stackoverflow.com/users/2365724/paoloc),感谢两位大神。 133 | 134 | 如果发现问题或建议请提[Issues](https://github.com/Robot-L/LambdaExceptionThrower/issues) 135 | ,如果对你有帮助,请点个Star,非常感谢~ ^_^ 136 | 137 | 扩展阅读: 138 | 139 | - [Java 8 Lambda function that throws exception?](https://stackoverflow.com/questions/18198176/java-8-lambda-function-that-throws-exception) 140 | - [How can I throw CHECKED exceptions from inside Java 8 streams?](https://stackoverflow.com/questions/27644361/how-can-i-throw-checked-exceptions-from-inside-java-8-streams) 141 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | io.github.luo-zhan 7 | lambda-exception-thrower 8 | 1.0.0-RELEASE 9 | LambdaExceptionThrower 10 | 写Lambda表达式不想要捕获异常怎么办,试试这个吧! 11 | https://github.com/luo-zhan/LambdaExceptionThrower 12 | 13 | 14 | 15 | 16 | 罗战 17 | luo-zhan@qq.com 18 | 19 | 20 | 21 | 22 | Github Issue 23 | https://github.com/luo-zhan/LambdaExceptionThrower/issues 24 | 25 | 26 | 27 | 28 | The Apache Software License, Version 2.0 29 | https://www.apache.org/licenses/LICENSE-2.0.txt 30 | 31 | 32 | 33 | 34 | scm:git@github.com:luo-zhan/LambdaExceptionThrower.git 35 | scm:git@github.com:luo-zhan/LambdaExceptionThrower.git 36 | git@github.com:luo-zhan/LambdaExceptionThrower.git 37 | 38 | 39 | 40 | 41 | oss 42 | OSS Snapshots Repository 43 | https://s01.oss.sonatype.org/content/repositories/snapshots/ 44 | 45 | 46 | oss 47 | OSS Staging Repository 48 | https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ 49 | 50 | 51 | 52 | 53 | release 54 | 55 | 56 | 57 | 58 | org.apache.maven.plugins 59 | maven-source-plugin 60 | 2.2.1 61 | 62 | 63 | package 64 | 65 | jar-no-fork 66 | 67 | 68 | 69 | 70 | 71 | 72 | org.apache.maven.plugins 73 | maven-javadoc-plugin 74 | 2.9.1 75 | 76 | private 77 | true 78 | UTF-8 79 | UTF-8 80 | UTF-8 81 | -Xdoclint:none 82 | 83 | 84 | 85 | package 86 | 87 | jar 88 | 89 | 90 | 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-gpg-plugin 96 | 1.6 97 | 98 | 99 | verify 100 | 101 | sign 102 | 103 | 104 | 105 | 106 | 107 | 108 | org.apache.maven.plugins 109 | maven-compiler-plugin 110 | 3.8.1 111 | 112 | 1.8 113 | 1.8 114 | true 115 | true 116 | UTF-8 117 | 118 | 119 | 120 | 121 | org.apache.maven.plugins 122 | maven-release-plugin 123 | 2.5.1 124 | 125 | 126 | org.eluder.coveralls 127 | coveralls-maven-plugin 128 | 4.3.0 129 | 130 | TsQHHPW9P2wm6TNuqLteuICP0XgoglGeq 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /src/main/java/com/robot/util/LambdaExceptionUtil.java: -------------------------------------------------------------------------------- 1 | package com.robot.util; 2 | 3 | import java.util.function.*; 4 | 5 | /** 6 | * Lambda异常处理工具类 7 | * 8 | * @author luozhan 9 | * @date 2019-05 10 | */ 11 | public class LambdaExceptionUtil { 12 | 13 | @FunctionalInterface 14 | public interface ConsumerWithExceptions { 15 | void accept(T t) throws E; 16 | } 17 | 18 | @FunctionalInterface 19 | public interface BiConsumerWithExceptions { 20 | void accept(T t, U u) throws E; 21 | } 22 | 23 | @FunctionalInterface 24 | public interface FunctionWithExceptions { 25 | R apply(T t) throws E; 26 | } 27 | 28 | @FunctionalInterface 29 | public interface BiFunctionWithExceptions { 30 | R apply(T t, U u) throws E; 31 | } 32 | 33 | @FunctionalInterface 34 | public interface SupplierWithExceptions { 35 | T get() throws E; 36 | } 37 | 38 | @FunctionalInterface 39 | public interface RunnableWithExceptions { 40 | void run() throws E; 41 | } 42 | 43 | @FunctionalInterface 44 | public interface PredicateWithExceptions { 45 | boolean test(T t) throws E; 46 | } 47 | 48 | @FunctionalInterface 49 | public interface BiPredicateWithExceptions { 50 | boolean test(T t, U u) throws E; 51 | } 52 | 53 | 54 | /** 55 | * 包装普通函数(Function) 56 | *

57 | * 注:方法签名中的" throws E "编译器会提示多余,但其实是为了将实际的异常向外传递,如果不这么做: 58 | * 1.外层代码中编译器将无法提示有异常需要处理 59 | * 2.也无法主动在外层捕获具体的异常,如果尝试try一个具体的异常,编译器将提示: 60 | * Exception 'XXX' is never thrown in the corresponding try block(在try语句体中永远不会抛出相应异常) 61 | */ 62 | public static Function wrapFunction(FunctionWithExceptions function) throws E { 63 | return t -> { 64 | try { 65 | return function.apply(t); 66 | } catch (Exception exception) { 67 | throwAsUnchecked(exception); 68 | return null; 69 | } 70 | }; 71 | } 72 | 73 | /** 74 | * 包装双入参普通函数(BiFunction) 75 | */ 76 | public static BiFunction wrapBiFunction(BiFunctionWithExceptions biFunction) throws E { 77 | return (t, u) -> { 78 | try { 79 | return biFunction.apply(t, u); 80 | } catch (Exception exception) { 81 | throwAsUnchecked(exception); 82 | return null; 83 | } 84 | }; 85 | } 86 | 87 | /** 88 | * 包装消费函数(Consumer) 89 | */ 90 | public static Consumer wrapConsumer(ConsumerWithExceptions consumer) throws E { 91 | return t -> { 92 | try { 93 | consumer.accept(t); 94 | } catch (Exception exception) { 95 | throwAsUnchecked(exception); 96 | } 97 | }; 98 | } 99 | 100 | /** 101 | * 包装双重消费函数(BiConsumer) 102 | */ 103 | public static BiConsumer wrapBiConsumer(BiConsumerWithExceptions biConsumer) throws E { 104 | return (t, u) -> { 105 | try { 106 | biConsumer.accept(t, u); 107 | } catch (Exception exception) { 108 | throwAsUnchecked(exception); 109 | } 110 | }; 111 | } 112 | 113 | 114 | /** 115 | * 包装生产函数(Supplier) 116 | */ 117 | public static Supplier wrapSupplier(SupplierWithExceptions function) throws E { 118 | return () -> { 119 | try { 120 | return function.get(); 121 | } catch (Exception exception) { 122 | throwAsUnchecked(exception); 123 | return null; 124 | } 125 | }; 126 | } 127 | 128 | /** 129 | * 包装条件函数(Predicate) 130 | */ 131 | public static Predicate wrapPredicate(PredicateWithExceptions predicate) throws E { 132 | return t -> { 133 | try { 134 | return predicate.test(t); 135 | } catch (Exception exception) { 136 | throwAsUnchecked(exception); 137 | return false; 138 | } 139 | }; 140 | } 141 | 142 | /** 143 | * 包装双入参条件函数(BiPredicate) 144 | */ 145 | public static BiPredicate wrapBiPredicate(BiPredicateWithExceptions predicate) throws E { 146 | return (t, u) -> { 147 | try { 148 | return predicate.test(t, u); 149 | } catch (Exception exception) { 150 | throwAsUnchecked(exception); 151 | return false; 152 | } 153 | }; 154 | } 155 | 156 | /** 157 | * 包装纯执行函数(Runnable) 158 | */ 159 | public static void wrapRunnable(RunnableWithExceptions runnable) throws E { 160 | try { 161 | runnable.run(); 162 | } catch (Exception exception) { 163 | throwAsUnchecked(exception); 164 | } 165 | } 166 | 167 | /** 168 | * 如果一段代码确保不会抛出所申明的异常,可以使用该方法进行包装 169 | * 如:new String(byteArr, "UTF-8")申明了UnsupportedEncodingException, 170 | * 但编码"UTF-8"是必定不会抛异常的,使用sure进行包装 171 | * String text = sure(() -> new String(byteArr, "UTF-8")) 172 | *

173 | * 注: sure方法有一定的风险,因为它隐藏了可能的异常申明,所以请谨慎使用,确保(sure)不会抛出异常才可以使用 174 | */ 175 | public static R sure(SupplierWithExceptions supplier) { 176 | try { 177 | return supplier.get(); 178 | } catch (Exception exception) { 179 | throwAsUnchecked(exception); 180 | // 其实不会执行到这行来,主要是用来解决在调用方法时idea提示的可能产生NPE的警告 181 | throw new UnreachableException(); 182 | } 183 | } 184 | 185 | /** 186 | * 同上 187 | */ 188 | public static void sure(RunnableWithExceptions runner) { 189 | try { 190 | runner.run(); 191 | } catch (Exception exception) { 192 | throwAsUnchecked(exception); 193 | // 其实不会执行到这行来,主要是用来解决在调用方法时idea提示的可能产生NPE的警告 194 | throw new UnreachableException(); 195 | } 196 | } 197 | 198 | @SuppressWarnings("unchecked") 199 | private static void throwAsUnchecked(Exception exception) throws E { 200 | throw (E) exception; 201 | } 202 | 203 | private static class UnreachableException extends RuntimeException { 204 | 205 | } 206 | 207 | } 208 | --------------------------------------------------------------------------------