閱讀621 返回首頁    go 阿裏雲 go 技術社區[雲棲]


java 反射機製

今天和同事一起開發一個Android App的時候,第一次接觸到了反射機製這樣一個東西,於是上網查了很多資料,看了一些文檔。現在終於有了一點了解,故將其寫下,大牛勿噴。

  首先,我們所學的編程語言大致可以分為兩種,第一種為靜態語言:C、C++、java ,這些語言的的變量類型一旦確定將不可更改;還有一類為動態語言:Perl、Python  這些語言的變量類型是可以更改的。但是java又區別於一般的靜態語言,因為其具有動態機製,所以java可以加載一個在運行時才確定的Class,得知其完整的構造,獲得具體的屬性以及運行其成員方法。

  所謂的java反射機製指的是:對於任意一個類,都能夠知道它的完成結構,對於任意一個對象都能夠調用它的方法,這種動態獲取對象的信息以及動態調用對象方法的機製成為java反射機製。

  這樣的定義並不好理解,最好的方法還是動手coding:首先我們寫一個很簡單的類:

Java代碼 
  1. public class Person {   
  2.    public String name;    
  3.    public int age;       
  4.    public String getName() {    
  5.        return name;    
  6.    }    
  7.    public Person()  
  8.    {  
  9.     name="liyahou";  
  10.     age=10;  
  11.    }  
  12.    public Person(String name)  
  13.    {  
  14.     this.name=name;  
  15.     this.age=23;  
  16.    }  
  17.    public void setName(String name) {    
  18.        this.name = name;    
  19.    }    
  20.    public int getAge() {    
  21.        return age;    
  22.    }    
  23.    public void setAge(int age) {    
  24.        this.age = age;    
  25.    }    
  26.    public String display()  
  27.    {  
  28.     return this.name+"  "+this.age;  
  29.    }  
  30. }  

 

現在我們用這個類為白老鼠,進行試驗:

example1:獲取屬性值

Java代碼 
  1. /** 
  2. * @param owner 傳入的實例 
  3. * @param filedName 要獲取的成員名 
  4. * @利用反射機製獲取類成員 
  5. */  
  6. public void getProperty(Object owner,String filedName)  
  7. {  
  8. Class instance=owner.getClass();  
  9. try {  
  10. Field filed=instance.getField(filedName);  
  11. Object property=filed.get(owner);  
  12. System.out.println(property.toString());  
  13. catch (NoSuchFieldException e) {  
  14. // TODO Auto-generated catch block  
  15. e.printStackTrace();  
  16. catch (SecurityException e) {  
  17. // TODO Auto-generated catch block  
  18. e.printStackTrace();  
  19. catch (IllegalArgumentException e) {  
  20. // TODO Auto-generated catch block  
  21. e.printStackTrace();  
  22. catch (IllegalAccessException e) {  
  23. // TODO Auto-generated catch block  
  24. e.printStackTrace();  
  25. }  
  26. }  
  27. public static void main(String[] args)  
  28. {  
  29.                 Person person=new Person();  
  30. person.setName("liyazhou");  
  31. ReflectDemo demo=new ReflectDemo();  
  32. demo.getProperty(person,"name");  
  33. }  

 

結果:liyazhou

代碼解析:

Class instance=owner.getClass();   獲取該對象的class

Field filed=instance.getField(filedName);  通過傳入的屬性名得到該屬性

Object property=filed.get(owner); 通過對象去獲取其屬性的值

 

 

example2:利用反射機製執行一個類的方法

Java代碼 
  1. /** 
  2.  * @param owner 
  3.  * @param methoadName 
  4.  * @param args 
  5.  * @throws NoSuchMethodException 
  6.  * @throws SecurityException 
  7.  * @throws IllegalAccessException 
  8.  * @throws IllegalArgumentException 
  9.  * @throws InvocationTargetException 
  10.  * @利用反射機製執行類的方法 
  11.  */  
  12. public void invokeClassMethod(Object owner,String methoadName,Object[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException  
  13. {  
  14.     Class instance=owner.getClass();//得到該類的class  
  15.     Class[] Args=new Class[args.length];  
  16.     for(int i=0;i<Args.length;i++)  
  17.     {  
  18.         Args[i]=args[i].getClass();  
  19.     }//構造該函數的參數類型  
  20.     Method method=instance.getMethod(methoadName, Args);//構造該方法  
  21.     System.out.println(method.invoke(owner, args)+"");//運行  
  22. }  

 

 

 

example 3:構造實例

Java代碼 
  1. public Object getNewInstance(String className, Object[] args)  
  2. {  
  3.     try {  
  4.         Class instance=Class.forName(className);//得到該類的Class  
  5.         Class[] arg=new Class[args.length];  
  6.         for(int i=0;i<args.length;i++)  
  7.         {  
  8.             arg[i]=args[i].getClass();  
  9.         }//構造方法所需的參數類型  
  10.         Constructor con=instance.getConstructor(arg);//構造構造器  
  11.         return con.newInstance(args);//構造實例  
  12.     } catch (ClassNotFoundException e) {  
  13.         // TODO Auto-generated catch block  
  14.         e.printStackTrace();  
  15.     } catch (NoSuchMethodException e) {  
  16.         // TODO Auto-generated catch block  
  17.         e.printStackTrace();  
  18.     } catch (SecurityException e) {  
  19.         // TODO Auto-generated catch block  
  20.         e.printStackTrace();  
  21.     } catch (InstantiationException e) {  
  22.         // TODO Auto-generated catch block  
  23.         e.printStackTrace();  
  24.     } catch (IllegalAccessException e) {  
  25.         // TODO Auto-generated catch block  
  26.         e.printStackTrace();  
  27.     } catch (IllegalArgumentException e) {  
  28.         // TODO Auto-generated catch block  
  29.         e.printStackTrace();  
  30.     } catch (InvocationTargetException e) {  
  31.         // TODO Auto-generated catch block  
  32.         e.printStackTrace();  
  33.     }  
  34.     return null;  
  35. }  

 

 

 

 

將java反射機製應用到工廠模式中:

  1. package Reflect;  
  2.    
  3. interface fruit{  
  4.     public abstract void eat();  
  5. }  
  6.    
  7. class Apple implements fruit{  
  8.     public void eat(){  
  9.         System.out.println("Apple");  
  10.     }  
  11. }  
  12.    
  13. class Orange implements fruit{  
  14.     public void eat(){  
  15.         System.out.println("Orange");  
  16.     }  
  17. }  
  18.    
  19. class Factory{  
  20.     public static fruit getInstance(String ClassName){  
  21.         fruit f=null;  
  22.         try{  
  23.             f=(fruit)Class.forName(ClassName).newInstance();  
  24.         }catch (Exception e) {  
  25.             e.printStackTrace();  
  26.         }  
  27.         return f;  
  28.     }  
  29. }  
  30. class hello{  
  31.     public static void main(String[] a){  
  32.         fruit f=Factory.getInstance("Reflect.Apple");  
  33.         if(f!=null){  
  34.             f.eat();  
  35.         }  
  36.     }  
  37. }  


現在就算我們添加任意多個子類的時候,工廠類就不需要修改。 

最後更新:2017-04-03 18:51:50

  上一篇:go 創業遐想:三千世界 致在橋上看風景的你
  下一篇:go 混亂的Android市場