Java中的反射Reflection

反射知识:

 获取类型模板对象有三种方式:

 1. 通过对象调用Object类中的getClass()方法来获取Class对象。

 2. 利用Class类中的forName( String className)方法来获取class对象。

      注:其中的className即为类全名(类全名  =包名.类名)。

 3. 通过类型名来获取class对象。

代码如下:

package day11.javaAdvance.exercise.reflection.Class;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ClassTest1 {

	public static void main(String[] args) throws Exception {
		/*
		 * 获取类型模板对象有三种方法:
		 */
		// 1.通过对象调用getClass方法获取Class对象
		Student stu = new Student("wangwang", 4);
		// 类型模板对象
		Class c1 = stu.getClass();
		System.out.println("1..." + c1);
		System.out.println("^^^" + c1.getName());
		// 2.利用Class对象来获取
		Class c2 = Class.forName("day11.javaAdvance.exercise.reflection.Class.Student");//方法:forName("类全名");
		System.out.println("2..." + c2);
		// 3.通过类型名来获取
		Class c3 = Student.class;
		System.out.println("3..." + c3);
		/*
		 * 获得此类的属性方法
		 */
		Field f[] = c1.getFields();
		for (int i = 0; i < f.length; i++) {
			System.out.println("属性有:" + f[i].getName());
		}
	}
}

class Student {
	public String name;
	public int age;

	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	private void show() {
	}

	public void print() {
		System.out.println("name=" + name + "," + "age=" + age);
	}

}

  

通过反射方法动态来获取类中的方法和构造函数(五步)

 1. 先获取类型模板对象:Class c=Student.class;

 2. 通过类型模板对象来获取构造函数: Class arr[]={}; Constructor con=c.getDeclaredConstructor(arr);

 3. 调用构造方法创建对象:Object obj1[]={}; Object obj=con.newInstance(obj1);

         System.out.println(obj);

 4. 获取方法:Method m=c.getMethod("show", arr);

 5. 利用Mehtod对象调用方法invoke

     Object o=m.invoke(obj, obj1);

package day11.javaAdvance.exercise.reflection.Class;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
 
/*
 * 重点: 通过反射方法动态来获取类中的方法以及构造函数(五步)。
 */
public class ClassTest3 {
 
    public static void main(String[] args) throws Exception {
         
 
        // 1. 获得类型模板对象
        Class cc = Studentd.class;
        // 2.通过类型模板对象来获取构造方法
        Class arrl[] = {};
        // 在java.lang.reflect 类 Constructor<T>包中
        Constructor cons = cc.getDeclaredConstructor(arrl);
        // 3.调用构造方法创建实例
        Object arr2[] = {};
        Object obj1 = cons.newInstance(arr2);
        System.out.println("%%% " + obj1);
 
        // 4.获取方法
        /*
         * public Method getMethod(String name, Class<?>... parameterTypes)
         *它反映此Class 对象所表示的类或接口的指定公共成员方法。
         */
        Method m = cc.getMethod("show", arrl);
        //5.invoke method 调用方法:
        /*
         *public Object invoke(Object obj,Object... args) 对带有指定参数的指定对象调用由此
         * Method 对象表示的底层方法。
         */
 
        Object obj = m.invoke(obj1, arr2);
 
        Constructor[] con = cc.getConstructors();
        for (int i = 0; i < con.length; i++) {
            System.out.println("@@@ " + con[i]);
        }
    }
 
}
 
class Studentd {
 
    public String name;
    private int age;
 
    public Studentd(String name, int age) {
        this.name = name;
        this.age = age;
    }
 
    public Studentd() {
 
    }
 
    public void show() {
        System.out.println("~~~~呵呵.....");
    }
    private void show1() {
        System.out.println("Hello!.....");
    }
    public void print() {
        System.out.println("name=" + name + "," + "age=" + age);
    }
}

  

package day11.javaAdvance.exercise.reflection.Class;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Properties;
 
public class ClassTest4 {
 
    public static void main(String[] args) {
        Biz1 b = new Biz1();
        b.finteat();
    }
 
}
 
class Biz1 {
    Animal animal = (Animal) AnimalFactory.getObject("impl");
 
    public void finteat() {
        animal.eat();
    }
}
 
class AnimalFactory {
    static Properties pro = new Properties();
    static {
        try {
            pro.load(new FileInputStream("config2.properties"));// 文件放在根目录下
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
 
    public static Object getObject(String name) {
        Object obj = null;
        String className = pro.getProperty(name);// name即是key键值,className即是value值。
        try {
            Class c = Class.forName(className);
            Class[] cl = {};
            Constructor con = c.getDeclaredConstructor(cl);
            Object[] obj1 = {};
            obj = con.newInstance(obj1);
            System.out.println("类全名是:" + obj);
 
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
 
        return obj;
    }
 
}
 
interface Animal1 {
    public void eat();
}
 
class Dog1 implements Animal {
    public void eat() {
        System.out.println("dog eatting ....");
    }
}
 
class Cat1 implements Animal {
    public void eat() {
        System.out.println("cat eatting....");
    }
}

其中的配置文件在config2.properties文件中。

配置文件中是键值对,其中的key=impl,value分别是Dog1类和Cat1类,以类全名方式赋值。其内容是:

impl= day11.javaAdvance.exercise.reflection.Class.Dog1
#impl=day11.javaAdvance.exercise.reflection.Class.Cat1

这样我们只要传递键值,即可得到配置文件中的value值即是代码中的:String className = pro.getProperty(name);得到的className即是value值。

使用配置文件的好处:不需在源代码中去修改代码,只需在配置文件中修改,这样很好体现了java的封装性这一特点。

posted @ 2013-04-10 15:17  coolbing  阅读(212)  评论(0编辑  收藏  举报