首页 > 编程语言 >Java中try{}catch的隐藏(如何优雅的实现异常块)

Java中try{}catch的隐藏(如何优雅的实现异常块)

时间:2022-12-12 15:41:26浏览次数:43  
标签:Java String 接口 try BufferedReader catch 异常 Class


写在前面

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

傍晚时分,你坐在屋檐下,看着天慢慢地黑下去,心里寂寞而凄凉,感到自己的​生命被剥夺​​了。当时我是个年轻人,但我害怕这样生活下去,衰老下去。在我看来,这是​​比死亡更可怕的事​​。--------王小波

在这之前,你需要知道以下几个概念:

行为参数化:

是​java8​​提出的,​​函数式编程​​​的一种思想,通过把​​代码包装为参数传递行为​​​,即把​​代码逻辑包装为一个参数​​,传到方法里。

Lambda表达式

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

函数式接口:

本质上是只有一个​抽象方法​​的​​普通接口​​​,可以被隐式的转换为​​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方法。

即​行为参数化是指导思想​​,​​Lambda表达式是表达方式​​​,​​函数式接口是实现手法​

如何隐藏

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

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

正常的写法:

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

隐藏之后的写法:

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

Java中try{}catch的隐藏(如何优雅的实现异常块)_开发语言

嗯,我们来看具体的实现:很简单,我们要做的,即把​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】​

描述一个行为,BufferReader -> String

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);
}

关于Java中try{}catch的隐藏就和小伙伴分享到这里


标签:Java,String,接口,try,BufferedReader,catch,异常,Class
From: https://blog.51cto.com/u_13474506/5929814

相关文章

  • java中OOM错误浅析(没有深入太多,一些粗浅的知识,可以温习用)
    嗯,生活加油鸭。。。。实习中遇到OOM错误GCoverheadlimitexceeded  问题,所以整理一下OOM异常问题:不对的地方请小伙伴留言^_^“阿里的开发手册”对OOM的描述:OOM,全称“......
  • 《深入理解Java虚拟机》读书笔记
    第一部分,走进Java第二部分,自动内存管理机制:第二章:Java内存区域与内存溢出异常一,Java中,虚拟机自动管理内存机制,不在需要为每一个new操作去写配对的delete和free操作,不容易......
  • 《java8高级应用与开发》读书笔记(二)
    写在前面本笔记涉及内容:类加载、反射、枚举、注解、国际化、格式化类加载:是指将类的class文件读入内存,并为之创建一个Java.lang.class对象。即当线程使用任何一个类时,系统都......
  • Ubuntu20.04 Java相关环境(JDK、Mysql、Redis、nacos、influxdb)部署以及运行
     重装了系统,系统版本号为:Ubuntu20.041、云平台登录云平台,选择要重装的服务器,关机、一键重装即可 2、安装jdk下载jdk-8u341-linux-x64.tar.gz,并复制到服务器目录下,比......
  • 使用javassist修改jar包里class文件
    参考:使用javassist修改jar包里class文件_淹死的鱼0719的博客-CSDN博客一、javassist依赖<dependency><groupId>org.javassist</groupId><artifactId>javassist......
  • Java调优
    https://zhuanlan.zhihu.com/p/573662668性能分析在系统层面能够影响应用性能的一般包括三个因素:CPU、内存和IO,可以从这三方面进行程序的性能瓶颈分析。1.CPU分析当程......
  • java中的时间api
    packageDataTimeTest;/*java.util.data|---java.sql.Data类1.两个构造器的使用>构造器一:Date():创建一个对应当前时间的Date对象>构造器二:创建指定毫......
  • javascript Promise
    Promise对象构造时需要一个参数,这个参数必须是一个函数。letprom=newPromise(function(resolve,reject){ console.log("Run"); //进行费时间的异步操作 ... /......
  • 说说真实Java项目的开发流程,以及面试前的项目准备说辞
      介绍项目是必不可少的Java面试环节,求职者需要借此证明自己真实Java项目的经验,如果再做的好的话,需要借此展开自己的亮点说辞。  不过之前如果只有学习项目经验,比......
  • 学习Java第一天
    MarkDown学习标题一级标题二级标题三级标题 字体MarkDown学习粗体MarkDown学习斜体MarkDown学习粗斜体MarkDown学习删除线效果引用MarkDown学习分割......