java 反射

Class 类:类的实例表示正在运行的 Java 应用程序中的类和接口。枚举是一种类,注释是一种接口。每个数组属于被映射为 Class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。一个Class对象表示表示的是一种类型,但这个类型未必是一种类,比如int.class是一个Class对象,而int不是类。

Field 类:提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。

Constructor 类:提供关于类的单个构造方法的信息以及对它的访问权限。这个类和 Field 类不同,Field 类封装了反射类的属性,而 Constructor 类则封装了反射类的构造方法。

Method 类:提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法。这个类不难理解,它是用来封装反射类方法的一个类。

如何获得字节码?
Class cls = Xxx.class;
Class cls = xx.getClass();
Class.forname(类名);  // 返回字节码:若内存中有加载该类,则他找到该类的字节码并返回,若无,则找到该类的路径,加载后返回。

要区别一个概念,这里获得的是类的字节码,与具体的对象无关。

如何获得实例?
Test t1=new Test();
Object t2 =t1.getClass().newInstance();
Object t3 =Class.forName("Test").newInstance();
newInstance方法调用没有参数的构造器,如果带参数就需要使用Constructor类。

Class类中的getFields、getMethods、getConstructors将返回类支持的public域、方法、和构造器数组,包括超类的公有成员。

Class类中的getDeclareFields、getDeclareMethods、getDeclareConstructors将返回类中声明的全部域、方法、和构造器数组,其中包括私有的和保护的,但不包括超类的成员。

Field、Method、Constructor都有一个getModifiers方法,可以使用其枚举值判断修饰符,或者Modifier.toString方法等解析。

AccessibleObjecte是Field、Method、Constructor公共超类,调用setAccessible(true)方法后可以对实例的保护和私有成员设置新值。这个特性是为调试、持久存储相似机制提供的。

使用Method类型作为函数参数可以实现c#中的委托,使用接口回调执行快些。
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

import javax.accessibility.AccessibleRole;

public class ReflectTest {

	public static int a = 47;

	private String str = "hello";

	public ReflectTest() {
	}

	public ReflectTest(String str) {
		this.str = str;
	}

	public String getStr(String str) {
		return this.str + "," + str;
	}

	public String getStr() {
		return str;
	}

	public static void MethodTest(Object object) {

	};

	public static void main(String[] args) throws Exception {

		ReflectTest instance = new ReflectTest();
		// 获取字节码
		Class clazz = Class.forName("ReflectTest");

	    // 获取字段信息
		Field fieldA = clazz.getField("a");
		fieldA.getName();
		fieldA.getType();
		Modifier.toString(fieldA.getModifiers());
		fieldA.getInt(instance);
		fieldA.get(instance);

		//设置私有成员
		Field fieldStr = clazz.getDeclaredField("str");
		fieldStr.setAccessible(true);
		// AccessibleObject.setAccessible(array, flag)
		fieldStr.set(instance, "abc");

		// 根据字节码构造实例
		Constructor<ReflectTest> constructor = clazz.getConstructor();
		instance = constructor.newInstance();// 无参
		instance = (ReflectTest) clazz.newInstance(); // 无参
		constructor = clazz.getConstructor(String.class);// 有参
		instance = constructor.newInstance("world");

		// 调用指针函数
		Method method1 = instance.getClass().getMethod("getStr");
		method1.invoke(instance);//无参
		method1 = instance.getClass().getMethod("getStr", String.class);
		method1.invoke(instance, "String str");// 有参
		method1 = instance.getClass().getMethod("MethodTest", Object.class);
		method1.invoke(null, "object");// 静态

	}

	// 使用反射编写通用的数组代码
	static Object GoodArryGrow(Object src) {
		Class cl = src.getClass();
		if (!cl.isArray())
			return null;
		Class componentType = cl.getComponentType();
		int length = Array.getLength(src);
		int newLength = length * 11 / 10 + 10;

		Object dest = Array.newInstance(componentType, newLength);
		System.arraycopy(src, 0, dest, 0, newLength);
		return dest;
	}
}
posted @ 2011-06-24 23:19  jinc  阅读(500)  评论(0编辑  收藏  举报