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. }  


现在就算我们添加任意多个子类的时候,工厂类就不需要修改。 

上一篇:通过Java反射调用方法


下一篇:【android-tips】android xml布局总结篇