[英]Replace InvocationHandler in java.lang.reflect.Proxy
[英]Why does a java.lang.reflect.Proxy require declaring checked exceptions when normal method invocation does not?
Java的Proxy
要求,在當前正在調用的接口方法上聲明從支持InvocationHandler
拋出的所有已檢查異常。
例如,給定一個測試界面,
interface Foo {
void bar1();
void bar2() throws IOException;
}
由始終拋出IOException
的InvocationHandler
支持的基於Proxy
的實例會產生兩種行為:
bar1()
將引發未經檢查的UndeclaredThrowableException
,其原因為IOException
。 bar2()
將直接引發IOException
。 現在,用普通的類實現此接口,並從這兩種方法中拋出IOException
。 任一方法的調用者都將直接收到IOException
。
為什么在虛擬機的其他部分似乎都沒有的情況下, Proxy
為什么要在運行時強制執行檢查的異常?
注意 :這種情況與強制包裝檢查的異常以拋出異常的方法截然不同,這種異常通常在諸如
} catch (e: IOException) {
throw new UncheckedIOException(e);
}
¹要么使用“偷偷摸摸的拋出”技術,要么用沒有經過檢查的異常的語言(例如Kotlin)編寫它,要么直接用字節碼實現該類。
我會說,這只是許多其他設計的選擇。 想法可能是防止純Java代碼在不可能發生的地方獲取檢查的異常-因為當時還不存在偷偷摸摸的異常(代理API在泛型存在之前就已創建,而偷偷摸摸的異常歸因於泛型類型擦除而起作用),其他編譯器和手動字節碼操作也不是我們期望的。 (稍后也添加了工具)因此,在創建代理類時,沒有人會期望從unchecked方法中獲取被檢查的異常,因此使它對代理類以相同的方式工作僅聽起來很自然。
仍然在Java中,想法是不允許隨機拋出檢查的異常,JVM不能在較低的杠桿上阻止這一事實是另一回事-但語言應盡量保持一致。
並且檢查的異常是Java規范的一部分,而不是jvm本身,因此其他語言可以執行其所需的任何操作-但是代理類是Java sdk的一部分,因此它們應遵循Java規范。 https://docs.oracle.com/javase/specs/jls/se12/html/jls-11.html#jls-11.2.3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.