反射機(jī)制是什么?
反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有的屬性和方法
;對于任意一個(gè)對象,都能夠調(diào)用他的一個(gè)方法和屬性,這種動(dòng)態(tài)獲取的信息以及
動(dòng)態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制。

反射機(jī)制能做什么?
 反射機(jī)制主要提供以下功能
  √ 在運(yùn)行時(shí)判斷任意一個(gè)對象所屬的類
  √ 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對象
  √ 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的的屬性和方法
  √ 在運(yùn)行時(shí)調(diào)用一個(gè)對象的方法
  √ 生成動(dòng)態(tài)代理

通過一個(gè)對象獲得完整的包名和類名

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

package com.hzg;public class TestReflect {    public static void main(String[] args) throws Exception {
        TestReflect testReflect = new TestReflect();
        System.out.println(testReflect.getClass().getName());        // 結(jié)果 com.hzg.TestReflect    }
}

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

通過一個(gè)對象獲得完整的屬性、方法

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

Class clazz = Person.class();//1、創(chuàng)建clazz對象的運(yùn)行時(shí)類Person對象Person p = (Person)clazz.getInstance();//2、通過反射調(diào)用運(yùn)行時(shí)的指定屬性Filed f1 = clazz.getField("name");
f1.set(p,"LiudeHua");//3、通過反射調(diào)用運(yùn)行時(shí)的指定的方法Method m1 = clazz.getMethod("show",String.class);
m1.invoke(p,"CHN");

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

注意:Class可不是關(guān)鍵字class,Class是類名字,class是個(gè)關(guān)鍵字標(biāo)識(shí)是類

獲取class的實(shí)例(3種方式)
 ?、僬{(diào)用運(yùn)行時(shí)類本身的.class屬性
    Class clazz = Person.class;
 ?、谕ㄟ^運(yùn)行時(shí)類的對象獲取
    Person p = new Person();
    Class clazz = p.getClass();
 ?、弁ㄟ^class的靜態(tài)方法獲取
    Class clazz = Class.forName("com.hzg.TestReflect");

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

package com.hzg;public class TestReflect {    public static void main(String[] args) throws Exception {
        Class<?> class1 = null;
        Class<?> class2 = null;
        Class<?> class3 = null;        // ① 靜態(tài)方法(一般采用這種形式)
        class1 = Class.forName("com.hzg.TestReflect");        // ② 運(yùn)行時(shí)類的對象獲取
        class2 = new TestReflect().getClass();        // ③ 類本身.class屬性
        class3 = TestReflect.class;
        System.out.println("類名稱   " + class1.getName());
        System.out.println("類名稱   " + class2.getName());
        System.out.println("類名稱   " + class3.getName());
    }
}

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

獲取一個(gè)對象的父類與實(shí)現(xiàn)的接口

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

 1 package com.hzg; 2 import java.io.Serializable; 3 public class TestReflect implements Serializable { 4     private static final long serialVersionUID = -2862585049955236662L; 5     public static void main(String[] args) throws Exception { 6         Class<?> clazz = Class.forName("com.hzg.TestReflect"); 7         // 取得父類 8         Class<?> parentClass = clazz.getSuperclass(); 9         System.out.println("clazz的父類為:" + parentClass.getName());10         // clazz的父類為: java.lang.Object11         // 獲取所有的接口12         Class<?> intes[] = clazz.getInterfaces();13         System.out.println("clazz實(shí)現(xiàn)的接口有:");14         for (int i = 0; i < intes.length; i++) {15             System.out.println((i + 1) + ":" + intes[i].getName());16         }17     }18 }

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

 

有了class實(shí)例以后,可以做什么呢?
 ?、?可以創(chuàng)建對應(yīng)運(yùn)行時(shí)類的對象
 ?、?獲取對應(yīng)運(yùn)行是類的完整的類的結(jié)構(gòu):屬性、方法、構(gòu)造器、包、泛型、注解、異常、內(nèi)部類。
    如 Method[] m1 = clazz.getMethods():獲取類和父類的所有public方法
    Method[] m1 = clazz.getDeclaredMethods():所有修飾符方法
    但是不含父類,只有這個(gè)類的中所有修飾符方法
 ?、?調(diào)用運(yùn)行是類中指定的結(jié)構(gòu)(屬性、方法、構(gòu)造器)
    √ 獲取指定屬性:Field name = clazz.getField("name");
    √ 設(shè)置指定public屬性:name.set(p,"hzg"); 
    √ 設(shè)置指定private屬性:
      Field name = clazz.geDeclaredtField("name");
      name.setAccessible(true);
      name.set(p,"hzg");
    √ 獲取指定的方法:Method m1 = clazz.getMethod("show");
    √ 調(diào)用指定的方法:
      Object obj = m1.invoke(p); 返回類型就是方法的返回類型

    √ 調(diào)用靜態(tài)方法:m1.invoke(Person.class);
    √ 調(diào)用帶參數(shù)的指定方法:
      Method m1 = clazz.getDeclatedMethod("show1",String.class);
      Object obj = m1.invoke(p,"hzg");

    √ 調(diào)用構(gòu)造器:Constructor con = clazz.getDeclaredConstructor();
    √ 調(diào)用帶參數(shù)構(gòu)造器,和帶參數(shù)方法一致

Java反射的應(yīng)用---代理

1、靜態(tài)代理(基于接口的多態(tài)性實(shí)現(xiàn)的靜態(tài)代理)

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

 1 interface ClothFactory{ 2   void productCloth(); 3 } 4 //被代理類 5 class NikeClothFactory implements ClothFactory{ 6   @Override 7   public void productCloth(){ 8     sysytem.out.printLn("NIKE工廠生產(chǎn)一批衣服"); 9   }10 }11 //代理類12 class ProxyFactory implements ClothFactory{13   ClothFactory cf;14   public ProxyFactory(ClothFactory cf){15     this.cf = cf;16   }17   @Override18   public void productCloth(){19     sysytem.out.printLn("代理類開始執(zhí)行,收代理費(fèi)1000");20     cf.productCloth();21   }22 }23 24 public class Test{25   public static void main(String[] args){26     //① 創(chuàng)建一個(gè)被代理對象27     NikeClothFactory nike = new NikeClothFactory ();28     //② 創(chuàng)建一個(gè)代理類對象29     ProxyFactory proxy = new ProxyFactory(nike);30     //③ 調(diào)用代理類對象的方法31     proxy.productCloth();32   }33 }

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

靜態(tài)代理總結(jié):
① 代理類和被代理類都實(shí)現(xiàn)同一個(gè)接口
② 代理類和被代理類都實(shí)現(xiàn)接口中的方法
缺點(diǎn):每個(gè)被代理類都需要一個(gè)代理類來完成,這樣程序需要過多的代理,思考:是否能有一個(gè)萬能的代理類完成全部的代理功能?

2、動(dòng)態(tài)代理(基于反射實(shí)現(xiàn)的動(dòng)態(tài)代理)

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

 1 interface ClothFactory{ 2   void productCloth(); 3 } 4 //被代理類 5 class NikeClothFactory inplements ClothFactory{ 6   @Override 7   public void productCloth(){ 8     sysytem.out.printLn("NIKE工廠生產(chǎn)一批衣服"); 9   }10 }11 //①必須實(shí)現(xiàn)InvocationHandler接口12 class MyInvocationHandler implements InvocationHandler{13   //② 聲明接口的代理類14   Object obj;15   //③ 創(chuàng)建一個(gè)方法實(shí)例化代理類16   public Object bind(Object obj){17     this.obj = obj;18     return Proxy.newProxyInstance(19     obj.getClass().geyClassLoder(),20     obj.getClass().getInterfaces(),this);21   }22   //④ 實(shí)現(xiàn)接口InvacationHandler的方法23   // 此方法實(shí)現(xiàn):當(dāng)調(diào)用代理類的對象方法的時(shí)候,都會(huì)轉(zhuǎn)換到它上調(diào)用24   @Override25   public Object invoke(Object proxy,Method method,Object[] args){26     Object returnVal = method.invoke(obj,args);27     return returnVal();28   }29 }30 //調(diào)用實(shí)現(xiàn)一下31 public class Test{32   public static void main(String[] args){33     //① 老規(guī)矩:創(chuàng)建一個(gè)被代理對象34     NikeClothFactory nike = new NikeClothFactory ();35     //②老規(guī)矩:創(chuàng)建一個(gè)代理類對象36     MyInvocationHandler hander = new MyinvocationHanlder();37     ClothFactory proxyCloth = (ClothFactory)hander.bind(nike);38     //③ 老規(guī)矩:調(diào)用代理類對象的方法39     proxyCloth .productCloth();40   }41 }

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動(dòng)開發(fā)培訓(xùn)

 

分類: Java

http://www.cnblogs.com/hzg110/p/6707030.html