隨筆 - 14, 文章 - 39, 評論 - 17, 引用 - 0
          數據加載中……

          JAVA的反射 (轉)

          JAVA的反射庫提供了一個非常豐富且精心設計的工具集,以便編寫能夠動態操縱JAVA代碼的程序,這項功能被大量的應用在JavaBeans中,他是JAVA的組建體系結構。

          JAVA中的代理可以在運行時創建一個實現一組接口的新類,這種功能只有在編譯時無法確定需要實現哪個接口時才有必要使用,對于應用程序設計人員來說,遇到這種情況的機會很少。然而對于系統程序設計人員來說,代理帶來的靈活性卻十分重要。??????????????????????????????????????????????????????????? ? ---摘自《JAVA核心技術卷2》

          有一些初學者對反射和代理有一點害怕,覺得這是高深的技術,不敢去碰,其實任何東西都沒有那么復雜,只要你去接觸,就會有收獲,這篇文章主要講解了反射和代理、AOP方面的知識,但是非常基本,如果有朋友不太明白可以發表評論,我會認真的解答的,下面我貼上兩個程序的代碼,很簡單大家看一下。

          --------------------------------------------------

          /**
          ?*這個程序的功能是通過反射技術得到一個類(SrcClass)的兩個String類型的成員變量
          ?*然后經過判斷對字符串進行處理
          ?*這個題目的特點:通過對API的閱讀了解Class類的使用方法
          ?*1、getDeclaredFields()得到所有的成員變量
          ?*2、Field類中的一些方法getType()
          ?*3、Field類繼承于AccessibleObject類,有一個setAccessible()方法,查看API得到他的用途
          ?**/
          import java.lang.reflect.Field;
          class SrcClass
          {
          ?private String name = "BeiJing.2008";//定義來兩個String類型的變量,訪問修飾都是私有的
          ?private String eMail = "BeiJing.2008@163.com";
          ?private int age = 25;
          ?
          ?
          ?public String toString()//覆蓋父類的toString方法,打印數據
          ?{
          ??return "Name:[ " + this.name + " ] EMail: [ " + this.eMail + " ] Age: [ " + this.age + " ]";
          ?}
          }

          public class TestClass
          {


          ?public static void main(String[] args)
          ?{
          ??SrcClass srcclass = new SrcClass();//首先實例化一個SrcClass類的實例,用于給amendString方法傳值
          ??TestClass testclass = new TestClass();//再實力化一個TestClass的實例
          ??
          ??System.out.println(srcclass);//打印一遍原始信息

          ??
          ??testclass.amendString(srcclass);//調用amendString方法
          ??System.out.println(srcclass);//打印一遍修改后的信息

          ?}
          ?
          ?
          ?public void amendString(Object cls)//用于修改通過代理得到srcclass的String成員變量,進行替換處理
          ?{
          ??try
          ??{
          ???Field[] fidles = cls.getClass().getDeclaredFields();//得到srcclass.getClass()類中的所有成員變量
          ???for(Field field : fidles)//增強for循環
          ???{
          ????if(field.getType().equals(java.lang.String.class))//判斷這個成員變量的類型是不是String類型的
          ????{???????????????????????????????????????????????? //如果返回true就進行處理
          ?????field.setAccessible(true);//設置這個變量不進行訪問權限檢查(我在SrcClass里設置的變量為private)
          ?????String newString = (String)field.get(cls);//通過Field類的get方法得到String成員變量
          ?????
          ?????field.set(cls,newString.replaceAll("BeiJing","China"));//進行替換,再調用Field類的set方法進行修改
          ????}
          ???}
          ??}
          ??
          ??catch(SecurityException e)//
          ??{
          ???e.printStackTrace();
          ??}
          ??
          ??catch (IllegalArgumentException e)
          ??{
          ???
          ???e.printStackTrace();
          ??}
          ??
          ??catch (IllegalAccessException e)
          ??{
          ???
          ???e.printStackTrace();
          ??}
          ??catch(Exception e)
          ??{
          ???e.printStackTrace();
          ??}
          ?}

          }

          ------------------------------------------------

          下面就是代理了,實現代理必須有4個類(一個接口3各類)

          public interface FooInterface {
          ??? public String printMassage();
          }

          ---------------------------------------------

          class ImplementFoo implements FooInterface {
          ????
          ????? public String printMassage()
          ??? {
          ?????????????? return "This is ImplementFoo ...";
          ??? }
          }

          ?

          ---------------------------------------------

          import java.lang.reflect.InvocationHandler;
          import java.lang.reflect.Method;
          import java.util.Date;

          class ImplementInvocationHandler implements InvocationHandler
          {
          ??? private Object foo;

          ??? public ImplementInvocationHandler(Object foo) //獲得將要運行類的實際對象
          ??? {
          ?????? this.foo = foo;???
          ??? }

          ??? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable //
          ??? {
          ??????? System.out.println("You want use " + proxy.getClass().getName() + "." +?

          ??????????????????????????????????????????method.getName() + " at " + new Date());
          ??????? return?? method.invoke(foo);//方法調用
          ??? }
          ???
          }

          ---------------------------------------------

          import java.lang.reflect.InvocationHandler;
          import java.lang.reflect.InvocationTargetException;
          import java.lang.reflect.Proxy;
          /**
          ?*?? InvocationHandler handler = new MyInvocationHandler(...);
          ???? Class proxyClass = Proxy.getProxyClass(
          ???????? Foo.class.getClassLoader(), new Class[] { Foo.class });
          ???? Foo f = (Foo) proxyClass.
          ???????? getConstructor(new Class[] { InvocationHandler.class }).
          ???????? newInstance(new Object[] { handler });

          ?*
          ?*/
          public class TestProxy {
          ???
          ?
          ??? public static void main(String[] args)
          ??? {
          ??????? ImplementFoo foo = new ImplementFoo();//實例化一個實現了FooInterface(自己定義的)接口的類
          ??????? InvocationHandler handler = new ImplementInvocationHandler(foo);
          ??????? //自己編寫實現InvocationHandler接口的類
          ??????? //并且將他實例化,ImplementInvocationHandler類中有一個構造函數需要接受一個ImplementFoo類的對象,? 因為我們將來
          ??????? //要使用ImplementFoo.printMassage方法,ImplementInvocationHandler類方法invoke中的method.invoke(foo)
          ??????? //需要知道他將調用誰的printMassage方法,所以我們要給ImplementInvocationHandler類傳遞一個ImplementFoo類的對象
          ???????
          ???????? Class proxyClass = Proxy.getProxyClass(FooInterface.class.getClassLoader(),FooInterface.class);
          ??????? //此時我們就要制造出一個代理類了,使用Proxy類的靜態方法getProxyClass,查看API得到答案
          ???????
          ????????? FooInterface f;
          ??????? try
          ??????? {
          ??????
          ??????????? f =? (FooInterface) proxyClass.getConstructor(new Class[] { InvocationHandler.class }).newInstance(handler);
          ??????????? System.out.println(f.hashCode());//動態實例化出一個代理類,并且調用他的hashCode、printMassage方法
          ??????????? System.out.println(f.printMassage());
          ??????????
          ??????? } catch (SecurityException ex) {
          ??????????? ex.printStackTrace();
          ??????? } catch (IllegalArgumentException ex) {
          ??????????? ex.printStackTrace();
          ??????? } catch (IllegalAccessException ex) {
          ??????????? ex.printStackTrace();
          ??????? } catch (InstantiationException ex) {
          ??????????? ex.printStackTrace();
          ??????? } catch (NoSuchMethodException ex) {
          ??????????? ex.printStackTrace();
          ??????? } catch (InvocationTargetException ex) {
          ??????????? ex.printStackTrace();
          ??????? }
          ?
          ??? }
          ???
          }



          posted on 2006-09-29 11:56 mlw2000 閱讀(233) 評論(0)  編輯  收藏 所屬分類: java

          主站蜘蛛池模板: 寿阳县| 大埔县| 达尔| 安远县| 安吉县| 郁南县| 宝鸡市| 海原县| 保山市| 柞水县| 宜良县| 湘潭县| 福安市| 高邑县| 河源市| 富锦市| 琼结县| 中山市| 视频| 开江县| 漳州市| 宜宾县| 平阳县| 同心县| 湘潭市| 綦江县| 通辽市| 郎溪县| 彭州市| 阳朔县| 伊宁县| 克拉玛依市| 滦南县| 泗洪县| 确山县| 苍梧县| 铅山县| 普陀区| 涞源县| 个旧市| 鹤峰县|