反射学习

1、先来一个最简单的。通过反射得到方法、字段

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

import org.junit.Test;

public class Reflect1 {
	@Test
	public void getMethods() throws Exception{ //得到所有(自己类中)的方法,包括private的方法
		Class<?> strClazz = Class.forName("java.lang.String");
		Method[] declaredMethods = strClazz.getDeclaredMethods();
		
		for(Method method : declaredMethods){
			System.out.println(method.getName());
		}
		
	}
	@Test
	public void getFields() throws Exception{ //得到所有(自己类中)的字段,包括private的字段
		Class<?> strClazz = Class.forName("java.lang.String");
		Field[] declaredFields = strClazz.getDeclaredFields();
		
		for(Field field : declaredFields){
			System.out.println(field.getName());
		}
		
	}
}

2、通过反射调用方法

import java.lang.reflect.Method;

import org.junit.Test;

/**
 * 通过反射调用方法
 * @author Administrator
 *
 */
public class Reflect2 {
	public Integer add(int num1 , int num2){
		return num1 + num2;
	}
	
	public String say(String name){
		return "hello "+name;
	}
	
	public String print(String str){
		return str;
	}
	public String print(){
		return "hello world";
	}
	
	/**
	 * 传统方式
	 * @description  
	 * @Date Jul 21, 2017
	 */
	@Test
	public void ordinaryTest(){
		Reflect2 r2 = new Reflect2();
		r2.add(1, 2);
		r2.say("张三");
		r2.print("hello world");
	}
	/**
	 * 通过反射调用方法
	 * @description  
	 * @Date Jul 21, 2017
	 */
	@Test
	public void reflectTest() throws Exception{
		Class<?> clazz = Reflect2.class; //得到class
		Reflect2 reflect2 = (Reflect2) clazz.newInstance(); //得到新的对象
		
		Method addMmethod = clazz.getMethod("add", new Class[]{int.class,int.class});
		Integer addResult = (Integer) addMmethod.invoke(reflect2, 1,3);
		System.out.println(addResult);
		System.out.println("----------------------------");
		
		Method sayMethod = clazz.getMethod("say", new Class[]{String.class});
		Object invoke = sayMethod.invoke(reflect2, "张三");
		System.out.println(invoke);
		System.out.println("----------------------------");
		
		Method printMethod = clazz.getMethod("print", new Class[]{String.class});
		Object invoke2 = printMethod.invoke(reflect2, "hello world");
		System.out.println(invoke2);
		System.out.println("----------------------------");
		Method printMethod2 = clazz.getMethod("print", new Class[]{});
		Object invoke3 = printMethod2.invoke(reflect2);
		System.out.println(invoke3);
	}
}

3、通过反射访问私有属性、方法

首先有个类

public class TestClass {
	
	private String name;
	
	public String address;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	private String say(){
		return "hello world";
	}
	private String say(String name){
		return "hello "+name;
	}
	
	
	public String say2(){
		return "hello world";
	}
	
	public String say2(String name){
		return "hello "+name;
	}
	
	
}

接着 通过反射访问上边类中的方法属性(包括私有方法属性)

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

import org.junit.Test;
/**
 * 反射访问私有方法,私有属性
 * @author Administrator
 *
 */
public class Reflect4 {
	/**
	 * 访问 public方法
	 * @description  
	 * @Date Jul 21, 2017
	 * @throws Exception
	 */
	@Test
	public void getPublicMethod() throws Exception{
		Class<?> clazz = TestClass.class;
		Object obj = clazz.newInstance();
		Method method1 = clazz.getDeclaredMethod("say2");
		Object value1 = method1.invoke(obj);
		System.out.println(value1);
		System.out.println("------------------------");
		Method method2 = clazz.getDeclaredMethod("say2",new Class[]{String.class});
		Object value2 = method2.invoke(obj, "张三");
		System.out.println(value2);
	}
	/**
	 * 访问私有方法
	 * @description  
	 * @Date Jul 21, 2017
	 * @throws Exception
	 */
	@Test
	public void testGetPrivateMethod() throws Exception{
		Class<?> clazz = TestClass.class;
		TestClass obj = (TestClass) clazz.newInstance();
		
		Method method1 = clazz.getDeclaredMethod("say");
		method1.setAccessible(true);  // 访问私有方法,如果不设置 会报错 java.lang.IllegalAccessException: Class com.test.reflect.Reflect4 can not access 
									 // a member of class com.test.reflect.TestClass with modifiers "private"
		Object value1 = method1.invoke(obj);
		System.out.println(value1);
		System.out.println("---------------------");
		Method method2 = clazz.getDeclaredMethod("say",new Class[]{String.class});
		method2.setAccessible(true);
		Object value2 = method2.invoke(obj, "张三");
		System.out.println(value2);
		System.out.println("---------------------");
		
		
	}
	/**
	 * 访问public 属性
	 * @description  
	 * @Date Jul 21, 2017
	 * @throws Exception
	 */
	@Test
	public void testGetPublicField() throws Exception{
		Class<?> clazz = TestClass.class;
		TestClass obj = (TestClass) clazz.newInstance();
		Field declaredField = clazz.getDeclaredField("address");
		declaredField.set(obj, "济南");
		System.out.println(obj.getAddress());
	}
	/**
	 * 访问private属性
	 * @description  
	 * @Date Jul 21, 2017
	 * @throws Exception
	 */
	@Test
	public void testGetPrivateField() throws Exception{
		Class<? extends Object> clazz = TestClass.class;
		TestClass obj = (TestClass) clazz.newInstance();
		Field declaredField = clazz.getDeclaredField("name");
		declaredField.setAccessible(true); // 访问私有属性,不设置会报错 java.lang.IllegalAccessException: Class com.test.reflect.Reflect4 can not access
										  // a member of class com.test.reflect.TestClass with modifiers "private"
		declaredField.set(obj, "张三");
		System.out.println(obj.getName());
		
	}
	
	
	
}

4、clazz.getMethods 和clazz.getDeclaredMethods的不同

另建一个类,继承 TestClass

public class TestClass2  extends TestClass{
	
	private String testSay(){
		return "hello world";
	}
	
	public String testSay2(){
		return "hello world";
	}
}

测试不同

/**
	 * clazz.getMethods 和clazz.getDeclaredMethods的不同
	 * @description  
	 * @Date Jul 21, 2017
	 */
	@Test
	public void testDifferent(){ 
		Class<?> clazz = TestClass2.class;
		Method[] methods = clazz.getMethods();  // 取出本类中非private的方法。同时会把 父类(父类的父类,父类的父类的父类,。。。)中的方法(不包括private)也取出来
		for(Method method : methods){
			System.out.println(method.getName());
		}
		System.out.println("-----------------------------");
		Method[] declaredMethods = clazz.getDeclaredMethods(); // 自己定义的类中的所有的方法
		for(Method method : declaredMethods){
			System.out.println(method.getName());
		}
	}

通过结果可以看出

clazz.getMethods();  // 取出本类中非private的方法。同时会把 父类(父类的父类,父类的父类的父类,。。。)中的方法(不包括private)也取出来。

而clazz.getDeclaredMethods(); // 自己定义的类中的所有的方法。

5、反射的简单应用,利用反射复制一个对象

首先创建一个两类。Child  和 ChildBean。利用反射将Child 复制为 ChildBean

Child类

public class Child {
	private Integer id;
	private String name;
	private Integer age;
	private String address;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "Child [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]";
	}
	
	
	
}

ChildBean 类

public class ChildBean {
	private Integer id;
	private String name;
	private Integer age;
	private String address;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	@Override
	public String toString() {
		return "ChildBean [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]";
	}
	
	
	
	
}

利用反射复制

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

import org.apache.commons.lang.StringUtils;
import org.junit.Test;
/**
 * 利用反射,复制
 * @author Administrator
 *
 */
public class Reflect3 {
	
	//  obj --->  newClazz
	public <T> T copyByReflect(Object obj, Class<T> newClazz) throws Exception{
		T newObj = newClazz.newInstance();
		
		Class<?> objClazz = obj.getClass();
		Field[] objFields = objClazz.getDeclaredFields();
		Field[] newFields = newClazz.getDeclaredFields();
		if(newFields.length > 0 && objFields.length >0){
			for(Field newField : newFields){
				String newFieldName = newField.getName();
				for(Field objField : objFields){
					String objFieldName = objField.getName();
					if(objFieldName.equals(newFieldName)){
						String upperFieldName = StringUtils.capitalize(objFieldName); //capitalize  首字母大写(如: name---> Name, id--->Id)
						// get obj field value
						Method getGetMethod = objClazz.getMethod("get"+upperFieldName);
						Object value = getGetMethod.invoke(obj); 
						// set newObj field value
						Method getSetmethod = newClazz.getMethod("set"+upperFieldName, objField.getType());
						getSetmethod.invoke(newObj, value); 
						
					}
				}
			}
		}
		
		
		return  newObj;
	}
		
	@Test
	public void testMain() throws Exception{
		Child child = new Child();
		child.setAddress("山东");
		child.setAge(18);
		child.setId(1);
		child.setName("张三");
		System.out.println("child:"+child);
		ChildBean newChild = this.copyByReflect(child, ChildBean.class);
		System.out.println("childBean:"+newChild);
	}
}

猜你喜欢

转载自1960370817.iteye.com/blog/2391326