关闭

java 反射 demo

454人阅读 评论(0) 收藏 举报

反射 代码 :

package wfg.reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.junit.Test;

/**
 * @Member接口 该接口可以获取有关类成员(域或者方法)后者构造函数的信息。
 *@AccessibleObject类 
 *                    该类是域(field)对象、方法(method)对象、构造函数(constructor)对象的基础类。它提供了将反射的对象标记为在使用时取消默认Java
 *                    语言访问控制检查的能力。
 *@Array类 该类提供动态地生成和访问JAVA数组的方法。
 *@Constructor类 提供一个类的构造函数的信息以及访问类的构造函数的接口。
 *@Field类 提供一个类的域的信息以及访问类的域的接口。
 *@Method类 提供一个类的方法的信息以及访问类的方法的接口。
 *@Modifier类 提供了 static 方法和常量,对类和成员访问修饰符进行解码。
 *@Proxy类 提供动态地生成代理类和类实例的静态方法。
 * 
 * @author wangkf
 */
public class ReflectTest {
	/**
	 * 可见getFields和getDeclaredFields区别 getFields返回的是申明为public的属性,包括父类中定义,
	 * getDeclaredFields返回的是指定类定义的所有定义的属性,不包括父类的。
	 */
	@Test
	public void getField() {
		Class<?> dataClass = ExtendData.class;
		// 使用getFields获取属性
		Field[] fields = dataClass.getFields();
		for (Field f : fields) {
			System.out.println("getFields:  " + f);
		}
		System.out.println();
		// 使用getDeclaredFields获取属性
		fields = dataClass.getDeclaredFields();
		for (Field f : fields) {
			System.out.println("getDeclaredFields:  " + f);
		}
	}

	/**
	 * 获得方法
	 */
	@Test
	public void getMethods() {
		Class<?> dataClass = ExtendData.class;
		Method[] methods = dataClass.getMethods();
		for (Method m : methods) {
			System.out.println("getMethods:  " + m);
		}
		System.out.println();
		// 使用getDeclaredMethods获取函数
		methods = dataClass.getDeclaredMethods();
		for (Method m : methods) {
			System.out.println("getDeclaredMethods:  " + m);
		}
	}

	/**
	 * 获取类的Constructor
	 */
	@Test
	public void getConstructors() {
		Class<?> dataClass = ExtendData.class;
		Constructor<?>[] constructors = dataClass.getConstructors();
		for (Constructor<?> m : constructors) {
			System.out.println("getConstructors:" + " " + m);
		}
		System.out.println();
		// 使用getDeclaredConstructors获取构造器
		constructors = dataClass.getDeclaredConstructors();
		for (Constructor<?> m : constructors) {
			System.out.println("getDeclaredConstructors:  " + m);
		}

	}

	/**
	 * 创建类实例
	 * 
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	@Test
	public void getNewInstance() throws InstantiationException,
			IllegalAccessException, SecurityException, NoSuchMethodException,
			IllegalArgumentException, InvocationTargetException {
		Object inst = null;
		Class<?> dataClass = ExtendData.class;
		Constructor<?> constructor;
		// 1、调用类的Class对象的newInstance方法,该方法会调用对象的默认构造器,如果没有默认构造器,会调用失败.
		inst = dataClass.newInstance();
		System.out.println("1: " + inst);
		// 2、调用默认Constructor对象的newInstance方法
		constructor = dataClass.getConstructor();
		inst = constructor.newInstance();
		System.out.println("2: " + inst);
		// 3、调用带参数Constructor对象的newInstance方法
		constructor = dataClass.getDeclaredConstructor(int.class, String.class);
		inst = constructor.newInstance(1, "123");
		System.out.println("3: " + inst);
	}

	/**
	 * 调用类的函数
	 * 
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws NoSuchMethodException
	 * @throws SecurityException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 */
	@Test
	public void fieldInvoke() throws InstantiationException,
			IllegalAccessException, SecurityException, NoSuchMethodException,
			IllegalArgumentException, InvocationTargetException {
		Class<?> dataClass = ExtendData.class;
		Object inst = dataClass.newInstance();
		Method logMethod = dataClass.getDeclaredMethod("pubExtendDataMethod",
				String.class);
		logMethod.invoke(inst, "Hello,world!");
	}

	/**
	 * 设置/获取类的属性值
	 * 
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws NoSuchFieldException
	 * @throws SecurityException
	 */
	@Test
	public void setFieldValue() throws InstantiationException,
			IllegalAccessException, SecurityException, NoSuchFieldException {
		Class<?> dataClass = ExtendData.class;
		Object inst = dataClass.newInstance();
		Field intField = dataClass.getField("pubExtendFieldId");
		intField.setInt(inst, 100);
		int value = intField.getInt(inst);
		System.out.println(value);
	}
	/**
	 * 动态创建代理类
	 */
//	代理模式:代理模式的作用=为其他对象提供一种代理以控制对这个对象的访问。
//	代理模式的角色:
//	抽象角色:声明真实对象和代理对象的共同接口
//	代理角色:代理角色内部包含有真实对象的引用,从而可以操作真实对象。
//	真实角色:代理角色所代表的真实对象,是我们最终要引用的对象。
//	动态代理:
//	java.lang.reflect.Proxy	
//	Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类
//	InvocationHandler	
//	是代理实例的调用处理程序 实现的接口,每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
//	 
//	动态Proxy是这样的一种类:
//	它是在运行生成的类,在生成时你必须提供一组Interface给它,然后该class就宣称它实现了这些interface。你可以把该class的实例当作这些interface中的任何一个来用。当然,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
//	在使用动态代理类时,我们必须实现InvocationHandler接口
	@Test
	public void useProxy(){
		Data data = new Data();
		InvocationHandler handler = new DynamicData(data);
		Class<?> classType = handler.getClass();
		IData iData = (IData)Proxy.newProxyInstance(classType.getClassLoader(),
		data.getClass().getInterfaces(), handler);
		System.out.println(iData.getClass());  
	}
}

其它类包:
package wfg.reflect;

public interface IData {
   public void getData();
}
package wfg.reflect;


public class Data implements IData {
	public int pubFieldId;
	public String pubFieldName;
	private int prvFieldId;

	public Data() {
		System.out.println("data默认 构造器 ");
	}

	Data(int arg1, String arg2) {
		pubFieldId = arg1;
		pubFieldName = arg2;
		System.out.println("data带参数构造器 ");
	}

	private void prvDataMethod() {
		System.out.println("data方法 :带参数构造器 ");
	}

	@Override
	public void getData() {
		System.out.println("getData");
	}
}

package wfg.reflect;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

class ExtendData extends Data {
	public int pubExtendFieldId;
	public String pubExtendFieldName;
	private int prvExtendFieldId;

	public ExtendData() {
		System.out.println("ExtendData默认 构造器 ");
	}

	public String pubExtendDataMethod(String str) {
		System.out.println("pubExtendDataMethod:  str=" + str);
		return str;
	}

	private void prvExtendDataMethod() {
		System.out.println("ExtendData私有方法:prvExtendDataMethod ");
	}

	ExtendData(int arg1, String arg2) {
		pubExtendFieldId = arg1;
		pubExtendFieldName = arg2;
		System.out
				.println("ExtendData带参构造函数:prvExtendDataMethod 参数:pubExtendFieldId = "
						+ arg1 + "  pubExtendFieldName = " + arg2);
	}

	public int getPrvExtendFieldId() {
		return prvExtendFieldId;
	}

	public void setPrvExtendFieldId(int prvExtendFieldId) {
		this.prvExtendFieldId = prvExtendFieldId;
	}
}

package wfg.reflect;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class DynamicData implements InvocationHandler {
	private Object obj;
	public DynamicData(Data data) {
		this.obj=data;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println("Method:"+ method + ",Args:" + args);
		method.invoke(obj, args);
		return null;
	}
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:27670次
    • 积分:496
    • 等级:
    • 排名:千里之外
    • 原创:19篇
    • 转载:3篇
    • 译文:1篇
    • 评论:11条
    文章分类
    最新评论