今天和同事一起开发一个Android App的时候,第一次接触到了反射机制这样一个东西,于是上网查了很多资料,看了一些文档。现在终于有了一点了解,故将其写下,大牛勿喷。
首先,我们所学的编程语言大致可以分为两种,第一种为静态语言:C、C++、java ,这些语言的的变量类型一旦确定将不可更改;还有一类为动态语言:Perl、Python 这些语言的变量类型是可以更改的。但是java又区别于一般的静态语言,因为其具有动态机制,所以java可以加载一个在运行时才确定的Class,得知其完整的构造,获得具体的属性以及运行其成员方法。
所谓的java反射机制指的是:对于任意一个类,都能够知道它的完成结构,对于任意一个对象都能够调用它的方法,这种动态获取对象的信息以及动态调用对象方法的机制成为java反射机制。
这样的定义并不好理解,最好的方法还是动手coding:首先我们写一个很简单的类:
- public class Person {
- public String name;
- public int age;
- public String getName() {
- return name;
- }
- public Person()
- {
- name="liyahou";
- age=10;
- }
- public Person(String name)
- {
- this.name=name;
- this.age=23;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public String display()
- {
- return this.name+" "+this.age;
- }
- }
现在我们用这个类为白老鼠,进行试验:
example1:获取属性值
- /**
- * @param owner 传入的实例
- * @param filedName 要获取的成员名
- * @利用反射机制获取类成员
- */
- public void getProperty(Object owner,String filedName)
- {
- Class instance=owner.getClass();
- try {
- Field filed=instance.getField(filedName);
- Object property=filed.get(owner);
- System.out.println(property.toString());
- } catch (NoSuchFieldException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SecurityException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- public static void main(String[] args)
- {
- Person person=new Person();
- person.setName("liyazhou");
- ReflectDemo demo=new ReflectDemo();
- demo.getProperty(person,"name");
- }
结果:liyazhou
代码解析:
Class instance=owner.getClass(); 获取该对象的class
Field filed=instance.getField(filedName); 通过传入的属性名得到该属性
Object property=filed.get(owner); 通过对象去获取其属性的值
example2:利用反射机制执行一个类的方法
- /**
- * @param owner
- * @param methoadName
- * @param args
- * @throws NoSuchMethodException
- * @throws SecurityException
- * @throws IllegalAccessException
- * @throws IllegalArgumentException
- * @throws InvocationTargetException
- * @利用反射机制执行类的方法
- */
- public void invokeClassMethod(Object owner,String methoadName,Object[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
- {
- Class instance=owner.getClass();//得到该类的class
- Class[] Args=new Class[args.length];
- for(int i=0;i<Args.length;i++)
- {
- Args[i]=args[i].getClass();
- }//构造该函数的参数类型
- Method method=instance.getMethod(methoadName, Args);//构造该方法
- System.out.println(method.invoke(owner, args)+"");//运行
- }
example 3:构造实例
- public Object getNewInstance(String className, Object[] args)
- {
- try {
- Class instance=Class.forName(className);//得到该类的Class
- Class[] arg=new Class[args.length];
- for(int i=0;i<args.length;i++)
- {
- arg[i]=args[i].getClass();
- }//构造方法所需的参数类型
- Constructor con=instance.getConstructor(arg);//构造构造器
- return con.newInstance(args);//构造实例
- } catch (ClassNotFoundException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (SecurityException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InstantiationException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- return null;
- }
将java反射机制应用到工厂模式中:
- package Reflect;
- interface fruit{
- public abstract void eat();
- }
- class Apple implements fruit{
- public void eat(){
- System.out.println("Apple");
- }
- }
- class Orange implements fruit{
- public void eat(){
- System.out.println("Orange");
- }
- }
- class Factory{
- public static fruit getInstance(String ClassName){
- fruit f=null;
- try{
- f=(fruit)Class.forName(ClassName).newInstance();
- }catch (Exception e) {
- e.printStackTrace();
- }
- return f;
- }
- }
- class hello{
- public static void main(String[] a){
- fruit f=Factory.getInstance("Reflect.Apple");
- if(f!=null){
- f.eat();
- }
- }
- }
现在就算我们添加任意多个子类的时候,工厂类就不需要修改。