今天搞懂了兩個問題
- check Exception 和 unchecked Exception 的區別
- try-catch和throw,throws的區別
今天遇到一個bug,需要這樣處理:Feign調用如果失敗了,則不更新數據庫
處理feign調用獲取返回值的方法是這么寫的
package com.common.Util;
import com.alibaba.fastjson.JSON;
import com.common.base.FeignResponse;
import com.common.enums.ErrorCodeEnum;
import com.service.feign.IFunction;
import com.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import java.util.Objects;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Supplier;
@Slf4j
public class FeignUtils {
public static <T, U, C, R> R getData(ErrorCodeEnum errorCode, T t, U u, C c , IFunction<T, U, C, FeignResponse<R>> function) {
FeignResponse<R> response;
try {
response = function.apply(t, u, c);
} catch (Exception e) {
log.error("Feign調用失敗, 調用參數:[{}][{}]", JSON.toJSONString(t) ,JSON.toJSONString(u), e);
throw new BusinessException(ErrorCodeEnum.FEIGN_CALL_FAILED.getCode(),"Feign調用失敗");
}
return handelResponse(errorCode, response);
}
public static <T, U, R> R getData(ErrorCodeEnum errorCode, T t, U u, BiFunction<T, U, FeignResponse<R>> function) {
FeignResponse<R> response;
try {
response = function.apply(t, u);
} catch (Exception e) {
log.error("Feign調用失敗, 調用參數:[{}][{}]", JSON.toJSONString(t) ,JSON.toJSONString(u), e);
throw new BusinessException(ErrorCodeEnum.FEIGN_CALL_FAILED.getCode(),"Feign調用失敗");
}
return handelResponse(errorCode, response);
}
public static <T, R> R getData(ErrorCodeEnum errorCode, T param, Function<T, FeignResponse<R>> function) {
FeignResponse<R> response;
try {
response = function.apply(param);
} catch (Exception e) {
log.error("Feign調用失敗, 調用參數:[{}]", JSON.toJSONString(param) , e);
throw new BusinessException(errorCode.getCode(),"Feign調用失敗", e);
}
return handelResponse(errorCode, response);
}
public static <T, R> R getData(ErrorCodeEnum errorCode, Supplier<FeignResponse<R>> function) {
FeignResponse<R> response;
try {
response = function.get();
} catch (Exception e) {
log.error("Feign調用失敗", e);
throw new BusinessException(errorCode.getCode(),"Feign調用失敗",e);
}
return handelResponse(errorCode, response);
}
private static <R> R handelResponse(ErrorCodeEnum errorCode, FeignResponse<R> response) {
if (Objects.isNull(response) || !Objects.equals("0", response.getCode())) {
throw new BusinessException(errorCode.getCode(),JSON.toJSONString(response.getMsg()));
}
return response.getData();
}
}
在try中捕獲異常,catch中throw異常,調用getData的方法還會繼續執行嗎?
斷點調試直接拋出異常,程序結束
try-catch和throw,throws的區別:
1.throw
throw 就是拋出一個異常,並獲取這個異常的引用,這個異常會被拋到外部的環境,由外部環境進行處理
try catch是直接處理,處理完成之后程序繼續往下執行,throw則是將異常拋給它的上一級處理,程序便不往下執行了。
2.throws
throws並不是拋出一個實際的Exception而是一個異常聲明,它聲明這個方法可能會拋出一個異常,注意是可能,所以在沒有異常的情況下也是可以用throws的,而throws本身的作用也是用來提高程序的健壯性,反過來,如果這個方法的的確確的有一個異常,那么編譯器會強制讓你加上throws這個異常聲明。
3.try catch
在try塊里經常放上可能會拋出異常的程序段
catch恰好就是處理try里拋出來的異常,其中catch的參數列表接收的是一個異常的引用,是throw拋出來的異常的引用,這樣我們就可以得到這個異常的對象
總結:在程序中有異常的代碼被try catch后,后邊的代碼能夠繼續執行,如果是throws 出來的,則運行到異常代碼處就會停止執行,拋出異常
寫了一段測試代碼驗證
public static void main(String[] args){ try { a(); } catch (Exception e) { e.printStackTrace(); } System.out.println("s"); } public static void a() { try { int a = 1; int b = a/0; } catch (Exception e) { throw new Exception("Feign調用失敗"); } }
上面代碼報錯:unhandled exception:java.lang.Exception
發現 throw new RuntimeException 不會報錯
而 throw new Exception 和 throw new IOException 會報錯
如果將測試代碼改為如下,則不報錯
public static void main(String[] args){ try { a(); } catch (Exception e) { e.printStackTrace(); } System.out.println("s"); } public static void a() throws IOException{ try { int a = 1; int b = a/0; } catch (Exception e) { throw new IOException("Feign調用失敗"); } }
或將測試代碼改為如下,也不報錯
public static void main(String[] args){ try { a(); } catch (Exception e) { e.printStackTrace(); } System.out.println("s"); } public static void a(){ try { int a = 1; int b = a/0; throw new IOException("Feign調用失敗"); } catch (Exception e) { } }
因為Exception是check異常,也就是必須在代碼層面直接捕獲處理的
checked: 一般是指程序不能直接控制的外界情況,是指在編譯的時候就需要檢查的一類exception,用戶程序中必須采用try catch機制處理或者通過throws交由調用者來處理。這類異常,主要指除了Error以及RuntimeException及其子類之外的異常。
unchecked:是指那些不需要在編譯的時候就要處理的一類異常。在java體系里,所有的Error以及RuntimeException及其子類都是unchecked異常。再形象直白的理解為不需要try catch 等機制處理的異常,可以認為是unchecked的異常。
+-----------+ | Throwable | +-----------+ / \ / \ +-------+ +-----------+ | Error | | Exception | +-------+ +-----------+ / | \ / | \ \ \________/ \______/ \ +------------------+ unchecked checked | RuntimeException | +------------------+ / | | \ \_________________/ unchecked