欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java的動態(tài)代理和靜態(tài)代理及反射常用API詳解

 更新時間:2024年01月15日 08:35:43   作者:小湯湯湯湯  
這篇文章主要介紹了Java的動態(tài)代理和靜態(tài)代理及反射常用API詳解,動態(tài)代理是一種在運行時動態(tài)生成代理對象的技術(shù),它是一種設計模式,用于在不修改原始對象的情況下,通過代理對象來間接訪問原始對象,并在訪問前后執(zhí)行額外的操作,需要的朋友可以參考下

JDK動態(tài)代理

我們看下JDK動態(tài)代理的實現(xiàn)步驟:

第一步:創(chuàng)建接口,JDK動態(tài)代理基于接口實現(xiàn),所以接口必不可少(準備工作)

第二步:實現(xiàn)InvocationHandler接口,重寫invoke方法(準備工作)

第三步:調(diào)用Proxy的靜態(tài)方法newProxyInstance方法生成代理實例(生成實例時需要提供類加載器,我們可以使用接口類的加載器即可)

第四步:使用新生成的代理實例調(diào)用某個方法實現(xiàn)功能。

我們的動態(tài)代理實現(xiàn)過程中根本沒有涉及到真實類實例。

靜態(tài)代理

 package ceshi1;
 public interface Iuser {
     void eat(String s);
 }
package ceshi1;
public class UserImpl implements Iuser {
  @Override
  public void eat(String s) {
    System.out.println("我要吃"+s);
  }
}
package ceshi1;
public class UserProxy implements Iuser {
  private Iuser user = new UserImpl();
  @Override
  public void eat(String s) {
    System.out.println("靜態(tài)代理前置內(nèi)容");
    user.eat(s);
    System.out.println("靜態(tài)代理后置內(nèi)容");
  }
}
package ceshi1;
public class ProxyTest {
  public static void main(String[] args) {
    UserProxy proxy = new UserProxy();
    proxy.eat("蘋果");
  }
}

動態(tài)代理

package ceshi1;
 public interface Iuser {
   void eat(String s);
 }
package ceshi1;
public class UserImpl implements Iuser {
  @Override
  public void eat(String s) {
    System.out.println("我要吃"+s);
  }
}
package ceshi1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class DynamicProxy implements InvocationHandler {
  private Object object;//用于接收具體實現(xiàn)類的實例對象
  //使用帶參數(shù)的構(gòu)造器來傳遞具體實現(xiàn)類的對象
  public DynamicProxy(Object obj){
    this.object = obj;
  }
  @Override
  public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
    System.out.println("前置內(nèi)容");
    method.invoke(object, args);
    System.out.println("后置內(nèi)容");
    return null;
  }
}
package ceshi1;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
public class ProxyTest {
  public static void main(String[] args) {
    Iuser user = new UserImpl();
    InvocationHandler h = new DynamicProxy(user);
    Iuser proxy = (Iuser) Proxy.newProxyInstance(Iuser.class.getClassLoader(), new Class[]{Iuser.class}, h);
    proxy.eat("蘋果");
  }
}

反射

JDK 提供的反射 API 進行反射調(diào)用:

Class clz = Class.forName("com.chenshuyi.reflect.Apple");
Method method = clz.getMethod("setPrice", int.class);
Constructor constructor = clz.getConstructor();
Object object = constructor.newInstance();
method.invoke(object, 4);

一般情況下我們使用反射獲取一個對象的步驟:

獲取類的 Class 對象實例

Class clz = Class.forName("com.zhenai.api.Apple");

根據(jù) Class 對象實例獲取 Constructor 對象

Constructor appleConstructor = clz.getConstructor();

使用 Constructor 對象的 newInstance 方法獲取反射類對象

Object appleObj = appleConstructor.newInstance();

而如果要調(diào)用某一個方法,則需要經(jīng)過下面的步驟:

獲取方法的 Method 對象

Method setPriceMethod = clz.getMethod("setPrice", int.class);

利用 invoke 方法調(diào)用方法

setPriceMethod.invoke(appleObj, 14);

反射常用API

在 Java API 中,獲取 Class 類對象有三種方法:

第一種,使用 Class.forName 靜態(tài)方法。當你知道該類的全路徑名時,你可以使用該方法獲取 Class 類對象。

Class clz = Class.forName("java.lang.String");

第二種,使用 .class 方法。

這種方法只適合在編譯前就知道操作的 Class。

Class clz = String.class;

第三種,使用類對象的 getClass() 方法。

String str = new String("Hello");

Class clz = str.getClass();

通過反射創(chuàng)建類對象

通過反射創(chuàng)建類對象主要有兩種方式:通過 Class 對象的 newInstance() 方法、通過 Constructor 對象的 newInstance() 方法。

第一種:通過 Class 對象的 newInstance() 方法。

Class clz = Apple.class;
Apple apple = (Apple)clz.newInstance();

第二種:通過 Constructor 對象的 newInstance() 方法

Class clz = Apple.class;
Constructor constructor = clz.getConstructor();
Apple apple = (Apple)constructor.newInstance();

通過 Constructor 對象創(chuàng)建類對象可以選擇特定構(gòu)造方法,而通過 Class 對象則只能使用默認的無參數(shù)構(gòu)造方法。下面的代碼就調(diào)用了一個有參數(shù)的構(gòu)造方法進行了類對象的初始化。

Class clz = Apple.class;
Constructor constructor = clz.getConstructor(String.class, int.class);
Apple apple = (Apple)constructor.newInstance("紅富士", 15);

我們通過 Class 對象的 getFields() 方法可以獲取 Class 類的屬性,但無法獲取私有屬性。

Class clz = Apple.class;
Field[] fields = clz.getFields();
for (Field field : fields) {
    System.out.println(field.getName());
}

而如果使用 Class 對象的 getDeclaredFields() 方法則可以獲取包括私有屬性在內(nèi)的所有屬性:

Class clz = Apple.class;
Field[] fields = clz.getDeclaredFields();
for (Field field : fields) {
    System.out.println(field.getName());
}

到此這篇關(guān)于Java的動態(tài)代理和靜態(tài)代理及反射常用API詳解的文章就介紹到這了,更多相關(guān)Java動態(tài)代理和反射內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論