Java 型別資訊詳解和反射機制
阿新 • • 發佈:2020-11-18
> 本文部分摘自 On Java 8
## RTTI RTTI(RunTime Type Information)執行時型別資訊,能夠在程式執行時發現和使用型別資訊,把我們從只能在編譯期知曉型別資訊並操作的侷限中解脫出來 傳統的多型機制正是 RTTI 的基本使用:假設有一個基類 Shape 和它的三個子類 Circle、Square、Triangle,現在要把 Circle、Square、Triangle 物件放入 List\
## 動態代理 代理是基本的設計模式之一,一個物件封裝真實物件,代替真實物件提供其他不同的操作,這些操作通常涉及到與真實物件的通訊,因此代理通常充當中間物件。下面是一個簡單的靜態代理的示例: ```java interface Interface { void doSomething(); } class RealObject implements Interface { @Override public void doSomething() { System.out.println("doSomething"); } } class SimpleProxy implements Interface { private Interface proxied; SimpleProxy(Interface proxied) { this.proxied = proxied; } @Override public void doSomething() { System.out.println("SimpleProxy doSomething"); proxied.doSomething(); } } class SimpleProxyDemo { public static void consumer(Interface iface) { iface.doSomething(); } public static void main(String[] args) { consumer(new RealObject()); consumer(new SimpleProxy(new RealObject())); } } ``` 當你希望將額外的操作與真實物件做分離時,代理可能會有所幫助,而 Java 的動態代理更進一步,不僅動態建立代理物件,而且可以動態地處理對代理方法的呼叫。在動態代理上進行的所有呼叫都會重定向到一個**呼叫處理程式**,該程式負責發現呼叫的內容並決定如何處理,下面是一個簡單示例: ```java class DynamicProxyHandler implements InvocationHandler { private Object proxied; DynamicProxyHandler(Object proxied) { this.proxied = proxied; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { return method.invoke(proxied, args); } } class SimpleDynamicProxy { public static void consumer(Interface iface) { iface.doSomething(); } public static void main(String[] args) { RealObject real = new RealObject(); Interface proxy = (Interface) Proxy.newProxyInstance( Interface.class.getClassLoader(), new Class[]{Interface.class}, new DynamicProxyHandler(real)); consumer(proxy); } } ``` 通過呼叫靜態方法 Proxy.newProxyInstance() 來建立動態代理,該方法需要三個引數:類載入器、希望代理實現的介面列表、以及介面 InvocationHandler 的一個實現。InvocationHandler 正是我們所說的呼叫處理程式,動態代理的所有呼叫會被重定向到呼叫處理程式,因此通常為呼叫處理程式的建構函式提供一個真實物件的引用,以便執行中間操作後可以轉發請