zl程序教程

您现在的位置是:首页 >  其他

当前栏目

如何优雅的实现异常块

2023-02-26 10:16:25 时间

在项目中,我们会遇到异常处理,对于运行时异常,需要我们自己判断处理。对于受检异常,需要我们主动处理。
但是繁琐的try{}caht嵌套在代码里,看着很不舒服,这里我们不讨论性能,就代码来讲,来看看如何将他隐藏起来。原理是不变的。变得是写法。下面我们来看如何优雅的处理异常块。

在这之前。你需要知道以下几个概念:
行为参数化:
是java8提出的,函数式编程的一种思想,通过把代码包装为参数传递行为,即把代码逻辑包装为一个参数,传到方法里。

Lambda表达式:
java8提出:Lambda表达式理解为简洁的表示可传递的匿名函数的一种方式,它没有名称,但它有函数体,参数列表,返回类型。可以抛出一个异常类型。包装代码逻辑为参数即使用Lambda表达式。

(福利推荐:阿里云、腾讯云、华为云服务器最新限时优惠活动,云服务器1核2G仅88元/年、2核4G仅698元/3年,点击这里立即抢购>>>

函数式接口:
本质上是只有一个抽象方法的普通接口,可以被隐式的转换为Lambda表达式,需要用注解定义(@FunctionalInterface)。默认方法和静态方法可以不属于抽象方法,可以在函数式接口中定义。

@FunctionalInterfacepublic interface ObjectMethodFunctionalInterface { void count(int i); String toString(); //same to Object.toString int hashCode(); //same to Object.hashCode boolean equals(Object obj); //same to Object.equals }

如果函数式接口中额外定义多个抽象方法,那么这些抽象方法签名必须和Object的public方法一样,接口最终有确定的类实现, 而类的最终父类是Object。 因此函数式接口可以定义Object的public方法。

    Class<?> clazz = Class.forName("类名");

这句代码想来小伙伴都不陌生。这是一个受检异常,需要抛出一个ClassNotFoundException。

正常的写法:

try {             Class<?> clazzOld = Class.forName("类名");         } catch (ClassNotFoundException e) {             e.printStackTrace();         }

隐藏之后的写法:

Class<?> clazzNew =classFind( o -> Class.forName(o),"类名");

如何优雅的实现异常块

嗯,我们来看具体的实现:很简单,我们要做的,即把Class<?> clazz = Class.forName("类名");当做一种行为去处理,接受一个String ,得到一个Class,所以我们要定义一个函数接口,描述这种行为。

/**  * @Auther: Liruilong  * @Date: 2020/7/29 15:50  * @Description: 由函数名获取元类Class实例  * 函数签名:   String ==> Class  */ @FunctionalInterface public interface ClassFindInterface {     Class<?> classNametoClass(String className)throws ClassNotFoundException; }

这里,因为我们的行为需要抛出异常。所以在接口里也抛出异常。

然后,我们需要定义一个方法,将我们的行为作为参数传进去,同时,捕获一下我们的异常。

public Class classFind(ClassFindInterface classFindInterface,String className){         Class<?> clazz =null;         try {             clazz = classFindInterface.classNametoClass(className);         } catch (ClassNotFoundException e) {             logger4j.error("˙·...·˙`˙·....·…┉═∞═…┉ ═∞═┈━═┈━═┈━═┈━═┈━═☆☆☆☆、"+e.getMessage()+"☆☆☆☆☆☆☆☆☆");             e.printStackTrace();         }         return clazz;     }

然后,我们可以调用我们的方法classFind方法,

Class<?> clazzNew =classFind( o -> Class.forName(o),"类名");

当然。其实这种思想并不简单的可以做捕获异常的处理,

我们来看一个Demo->

文本文件转换为字符串:
在我看来;将文本文件转换为字符串,我们需要使用高级流包装低级流,然后做缓存读出来。这里,我们不可避免的会遇到异常处理,流的关闭等操作,下面我们将这些代码都异常起来。专心写读的逻辑即可。
我的思路:
我对java IO用的不是很熟,大家有好的方法请留言,相互学习:

FileInputStream fileInputStream = new FileInputStream(file)) InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream)) BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) String str = bufferedReader.readLine()

字节流-》字符流-》字符缓存流 即 将字节流转换为字符流之后在用高级流包装。
所以我的思路是避免在逻辑里出现太多的IO流关闭,和异常捕获,专心处理读取逻辑即可,结合以下两种技术:

  • try(){}【自动关闭流,1.7支持】
  • lambda特性来实现【行为参数化,1.8】
package com.liruilong.demotext.service.utils.interfaceutils;   import java.io.BufferedReader; import java.io.IOException;   /**  * @Description : 函数接口,描述BufferedReader ->String的转化方式  * @Author: Liruilong  * @Date: 2020/3/17 15:44  */ @FunctionalInterface public interface InputStreamPeocess {     /**      * @Author Liruilong      * @Description 方法签名 BufferedReader ->String      * @Date 15:47 2020/3/17      * @Param [inputStream]      * @return com.liruilong.demotext.service.utils.InputStream      **/       String peocess(BufferedReader bufferedReader) throws IOException; }

执一个行为,任何BufferReader -> String的Lambda表达式都可以作为参数传入。只要符合peocess方法的签名即可。

 /**      * @return java.lang.String      * @Author Liruilong      * @Description 环绕处理      * @Date 17:14 2020/3/17      * @Param [inputStreamPeocess, file]      **/       public static String fileToBufferedReader(InputStreamPeocess inputStreamPeocess, File file) {          string  resoult= null;         try (FileInputStream fileInputStream = new FileInputStream(file)) {             try (InputStreamReader inputStreamReader = new InputStreamReader(fileInputStream)) {                 try (BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) {                     resoult = inputStreamPeocess.peocess(bufferedReader);                 }             }         } catch (IOException e) {             e.printStackTrace();         } finally {             return resoult ;         }     }

执行

/**      * @return java.lang.String      * @Author Liruilong      * @Description 文件转字符串      * @Date 17:22 2020/3/17      * @Param [file]      **/       public static String readJsonToString(File file) {         return  fileToBufferedReader((bufferedReader) -> {             String str = null;             StringBuilder stringBuilder = new StringBuilder();             while ((str = bufferedReader.readLine()) != null) {                 stringBuilder.append(str);             }             return stringBuilder.toString();         }, file);     }

如何优雅的实现异常块


本站部分内容转载自网络,版权属于原作者所有,如有异议请联系QQ153890879修改或删除,谢谢!
转载请注明原文链接:如何优雅的实现异常块

你还在原价购买阿里云、腾讯云、华为云、天翼云产品?那就亏大啦!现在申请成为四大品牌云厂商VIP用户,可以3折优惠价购买云服务器等云产品,并且可享四大云服务商产品终身VIP优惠价,还等什么?赶紧点击下面对应链接免费申请VIP客户吧:

1、点击这里立即申请成为腾讯云VIP客户

2、点击这里立即注册成为天翼云VIP客户

3、点击这里立即申请成为华为云VIP客户

4、点击这里立享阿里云产品终身VIP优惠价

喜欢 (0)
[[email protected]]
分享 (0)