天天看點

反射與動态代理簡直是影視圈的神馬組合

反射與動态代理簡直是影視圈的神馬組合

Java可以在運作的時候知道對象的資訊,這主要展現在Java的兩個功能,RTTI和反射。

反射

上篇文章我們講了RTTI的一些特性,它可以确定運作時的對象類型,這個類是在編譯的時候是确定的,這樣才能通過編譯後的Class檔案來加載類對象。當我們在編譯時無法擷取類資訊的時候,就可以考慮使用反射,既然本地沒有Class檔案,可能就是通過網絡擷取Class檔案,這時候我們就可以使用反射來擷取類資訊。

JDK中有個java.lang.reflect反射包,裡面定義了反射用到的一些類,

代理

反射往往與動态代理相結合使用,所謂代理就是自己由于各種各樣的原因不好抛頭露面,有一個代理類來幫它完成一件事情,代理類往往在真正方法執行的前後添加邏輯。

下面我們舉個代理模式使用的例子來說明一些

靜态代理

定義一個接口:

interface Interface {
  void doSomething();
}
           

定義真正的對象:

class RealObject implements Interface {
  public void doSomething() { 
    System.out.println("簡單輸出"); 
  }
}
           

定義代理類:

class SimpleProxy implements Interface {
  private Interface proxied;
  public SimpleProxy(Interface proxied) {
    this.proxied = proxied;
  }
  public void doSomething() {
    System.out.println("使用代理類");
    proxied.doSomething();
  }
}  
           

使用:

new SimpleProxy(new RealObject()).doSomething();
           

這樣我們看一下代碼,,輸出結果如下會先輸出

使用代理類

,然後是

簡單輸出

這是靜态代理的實作,代理類需要我們定義,而動态代理就不一樣了。

動态代理

動态代理可以動态建立代理并動态調用需要代理的方法。

定義動态代理類,這裡我們使用實作InvocationHandler接口來,并重寫他的invoke()方法

動态代理類:

class DynamicProxyHandler implements InvocationHandler {
  private Object proxied;
  public DynamicProxyHandler(Object proxied) {
    this.proxied = proxied;
  }
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("代理類: " + proxy.getClass() + ", 方法: " + method + ", 參數: " + args);
    if(args != null)
      for(Object arg : args)
        System.out.println("  " + arg);
    return method.invoke(proxied, args);
  }
}  
           

動态代理類的這一個invoke()方法的重寫就夠用了,當接口定義其他方法的時候,靜态代理類需要同時實作接口的其他方法,而動态代理類就不需要了,這就是它的優勢所在。

使用:

Interface proxy = (Interface)Proxy.newProxyInstance(
      Interface.class.getClassLoader(),
      new Class[]{ Interface.class },
      new DynamicProxyHandler(new RealObject()));
      
 proxy.doSomething();
           

運作結果:

代理類:class $Proxy0, 方法:public abstract void Interface.doSomething(),參數: null

這裡定義的動态代理類和靜态代理類差不多,但比靜态代理類稍微複雜一點。

總結

❤️ 感謝大家

  1. 歡迎關注我❤️,點贊👍🏻,評論🤤,轉發🙏
  2. 關注

    周結論本人

    ,定期為你推送好文,還有群聊不定期抽獎活動,可以暢所欲言,與大神們一起交流,一起學習。
  3. 有不當之處歡迎批評指正。