在項目中,我們會遇到異常處理,對于運作時異常,需要我們自己判斷處理。對于受檢異常,需要我們主動處理。
但是繁瑣的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方法。
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);
}