黑马程序员 日记五:反射机制学习总结

---------------------- android培训java培训、期待与您交流! ----------------------

反射机制,据我的理解,就是把类中的各个成份,映射成类后,在程序运行时,动态的改变程序结构和其中成份的值。

反射中的各种操作,都要基于java.lang.Class类。

API文档中,对Class类有如下描述:

Class类的一个实例,表示的是一个运行中的java程序中,所包含的ClassInterface.一个枚举类型,是一种类;一个注释,是一种借口,每一个数组也属于一个被反射为一个拥有相同类型元素和维数的数组的Object类;java的基本数据类型((booleanbytecharshortintlong,float, and double )和关键字void也可以被反射为一个类。

Class类没有公开的构造方法,取而代之的是当java虚拟机载入或者被classloader的方法载入时,会自动被创建出来。

获得Class对象有三种方法:

1.直接用类名.Class,例如:Class css = Strng.Class;

2.用实例化对象与getClass()方法,例如:Class css = new String().getClass();

3.这种是最常用的方法,用Class类的静态方法forName (),传入一个完整包名类名字符串,例如:Class css = Class.forName("java.lang.String");

一、对构造方法的反射

构造方法的类为java.lang.reflect.Constructor类,通过Class类的getConstructor方法得到,再用得到的Constructor实例对象调用newInstance方法,生成该类对象的实例,例如:

要用反射的方法构造一个字符串,以下代码相关异常已抛出

	Class cls = String.class;	//取得String类的一个实例化对象;
	Constructor contor = cls.getConstructor(String.class);//取得使用String创建新String的构造方法类的实例化对象;
	String welcomeStr = (String)contor.newInstance("欢迎光临");//利用构造方法的实例化对象创建一个新的String,注意:使用构造方法实例化对象时候,一定要和所取得的构造方法中参数和类型一致,否则会在运行时出现IllegalArgumentException异常。
	System.out.println(welcomeStr);

另外,若构造方法为私有的,则可以如下获得Contructor

	Constructor<Man> constructor = 	Man.class.getDeclaredConstructor(String.class, int.class);
	constructor.setAccessible(true);
	Man xiaogang = (Man)constructor.newInstance("小刚", 34);
	System.out.println(xiaogang);
	
public class Man extends Person{
	@Override
	public String toString() {
		return name + '\t' + age;
	}

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

其中,getDeclaredConstructor,constructor.setAccessible(true)是通过暴力反射方式,来取得和使用Contructor实例化对象的。

二、对成员变量的反射

表示成员变量的类为java.lang.reflect.Field类,通过Class类中的getField()方法得到,再用Field类中的get方法得到具体对象中的该成员变量的值,例如:

	//已抛出相关异常
public class Man extends Person{
	@Override
	public String toString() {
		return name + '\t' + age;
	}

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

对上边的Man类取得公有的成员变量name

	Man xiaoming = new Man ("小明", 22);
	Class cls = xiaoming.getClass();
	Field field = cls.getField("name");
	System.out.println(field.get(xiaogang));

这是对公有成员变量的反射,对私有成员变量应该如下方式反射:

	Class cls = xiaoming.getClass();
	Field ageFie = cls.getDeclaredField("age");
	ageFie.setAccessible(true);
	System.out.println (ageFie.get(xiaoming));

在这里,对Man类中的age字段通过反射得到,但是,age字段是私有的,所以,要做改动Field ageFie = cls.getDeclaredField("age"),用来取得声明过的成员变量,不管是不是私有的,ageFie.setAccessible(true),暴力反射,才能得到私有成员变量。

二、对成员方法的反射

在反射中表示成员方法的是java.lang.reflect..Method,通过ClassgetMethod方法得到一个Method的实例化对象,再通过invoke方法,执行得到的Method的实例化对象。例如:

	Class strClass = String.class;
	Method method = strClass.getMethod("charAt", int.class);	//第一个参数为方法名;
	String myStr = "we are the world";
	System.out.println(method.invoke(myStr, 4));
	若为私有的方法则变为如下形式就可以了
	Method eatMethod = cls.getDeclaredMethod("eat", int.class);
	eatMethod.setAccessible(true);

另外,在invoke方法调用反射后的Method对象的时候,若原来方法是静态的,则invoke里传参的时候,第一个参数为null

注:对数组的反射,主要是对java.lang.reflect..Array的操作,不再赘述。


---------------------- android培训java培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net/heima

猜你喜欢

转载自blog.csdn.net/boybeak/article/details/7561549