異常-代理-泛型

HandKnock發表於2020-10-26

異常體系

Exception 和 Error的區別

Exception 和 Error 都繼承於 Throwable,在 Java 中,只有 Throwable 型別的物件才能被 throw 或者 catch,它是異常處理機制的基本組成型別。

Exception 和 Error 體現了 Java 對不同異常情況的分類。

  • Exception 是程式正常執行中,可以預料的意外情況,可能並且應該被捕獲,進行相應的處理。
  • Error 是指在正常情況下,不大可能出現的情況,絕大部分 Error 都會使程式處於非正常、不可恢復的狀態。既然是非正常,所以不便於也不需要捕獲,常見的 OutOfMemoryError 就是 Error 的子類。

Exception 又分為 checked Exception 和 unchecked Exception。

checked Exception 在程式碼裡必須顯式的進行捕獲,這是編譯器檢查的一部分。

unchecked Exception 也就是執行時異常,類似空指標異常、陣列越界等,通常是可以避免的邏輯錯誤,具體根據需求來判斷是否需要捕獲,並不會在編譯器強制要求

return問題答案

catch塊和finally塊中的程式碼都執行了,但是finally塊中的返回值覆蓋了catch中的return值

try,catch,finally中可以同時都出現return,一旦return寫在最後,要麼在try,catch,finally都不寫return,要麼在try中寫return,才能通過編譯。需要特別注意的是,基本資料型別(就不再強行用記憶體解釋了),簡單點記憶就是基本資料型別返回值是“覆蓋”,引用型別是“疊加”

https://juejin.im/post/5a9cec866fb9a028d042ef47//陷阱

一般情況下finally塊中的程式碼是一定會被執行,除非JVM停止工作

缺點

影響效能
程式進入catch裡,非常耗資源

Try/with/resources

return,break,continue

return的功能是結束一個方法

continue的功能和break有點類似,區別是continue只是中止本次迴圈,接著開始下一次迴圈

break則是完全中止整個迴圈

答案是否定的,也就是不會列印輸出這句話。

​不論try塊是正常結束,還是中途非正常退出,也就是發生各種異常,finally塊確實都會執行。然而在這個程式中,程式中try塊中增加了System.exit(0);來退出程式,try語句根本就沒有結束其執行過程,System.exit(0);將停止當前執行緒和所有其他當場死亡的執行緒。finally塊並不能讓已經停止的執行緒繼續執行

代理

Proxy代理模式是一種結構型設計模式,主要解決的問題是:在直接訪問物件時帶來的問題

其目的就是為其他物件提供一個代理以控制對某個物件的訪問。代理類負責為委託類預處理訊息,過濾訊息並轉發訊息,以及進行訊息被委託類執行後的後續處理

解耦合

靜態代理

優點
解耦合、隱藏實現
缺點

  • 代理類和委託類實現了相同的介面,代理類通過委託類實現了相同的方法。這樣就出現了大量的程式碼重複
  • 代理物件只服務於一種型別的物件,如果要服務多型別的物件。勢必要為每一種物件都進行代理,靜態代理在程式規模稍大時就無法勝任了

動態代理

動態代理是在執行時,通過反射機制實現動態代理,並且能夠代理各種型別的物件

通過InvocationHandler代理不同型別的物件,如果我們把對外的介面都通過動態代理來實現,那麼所有的函式呼叫最終都會經過invoke函式的轉發,因此我們就可以在這裡做一些自己想做的操作,比如日誌系統、事務、攔截器、許可權控制等。這也就是AOP(面向切面程式設計)的基本原理

        InvocationHandler handler = new ProxyHandler(hello);
        HelloInterface proxyHello = (HelloInterface) Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), handler);
        proxyHello.sayHello();
        
        public class ProxyHandler implements InvocationHandler{
    private Object object;
    public ProxyHandler(Object object){
        this.object = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("Before invoke "  + method.getName());
        method.invoke(object, args);
        System.out.println("After invoke " + method.getName());
        return null;
    }
}

動態代理的實現方式,AOP的實現方式

  1. JDK動態代理:利用反射機制生成一個實現代理介面的匿名類,在呼叫具體方法前呼叫InvokeHandler來處理。
  2. CGlib動態代理:利用ASM(開源的Java位元組碼編輯庫,操作位元組碼)開源包,將代理物件類的class檔案載入進來,通過修改其位元組碼生成子類來處理。
  3. 區別:JDK代理只能對實現介面的類生成代理;CGlib是針對類實現代理,對指定的類生成一個子類,並覆蓋其中的方法,這種通過繼承類的實現方式,不能代理final修飾的類

泛型

簡單的說,意義和作用有:
  型別的引數化,就是可以把型別像方法的引數那樣傳遞。這一點意義非凡。
  泛型使編譯器可以在編譯期間對型別進行檢查以提高型別安全,減少執行時由於物件型別不匹配引發的異常。
  
  Java 語言中引入泛型是一個較大的功能增強
  消除強制型別轉換
  型別安全
  
泛型中的型別擦除是什麼
https://www.cnblogs.com/the-wang/p/10234727.html

https://www.cnblogs.com/coprince/p/8603492.html

https://www.jianshu.com/p/986f732ed2f1

相關文章