Java的反射reflect使用

在Java中提供了reflect类,可以帮助我们完成Java的类的属性的遍历,并且可以使用它完成属性的修改。以下范例中提供了两种操作方法:

1. 直接采用field.get和field.set操作

2. 使用Object.getClass().getMethod()方法获取field的getter和setter,然后用method.invoke()实现

范例如下:

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

public class TestJava{
	public static void reflectTest(Object model) throws NoSuchMethodException,  
					 IllegalAccessException, IllegalArgumentException,  
					 InvocationTargetException {  
		 // 获取实体类的所有属性,返回Field数组  
		 Field[] field = model.getClass().getDeclaredFields();  
		 // 遍历所有属性  
		 for (int j = 0; j < field.length; j++) {  
				 // 获取属性的名字  
				 String name = field[j].getName();  
				 // 将属性的首字符大写,方便构造get,set方法  
				 name = name.substring(0, 1).toUpperCase() + name.substring(1);  
				 // 获取属性的类型  
				 String type = field[j].getGenericType().toString();  
				 // 如果type是类类型,则前面包含"class ",后面跟类名  
				 System.out.println("属性为:" + name);  
				 System.out.println("类型为:" + type);
				
				try
				{
					Class typeClass = field[j].getType();  
				
					//使用field的set和get进行操作。
					//对于private变量,一定要使用field.setAccessible(true);才可以进行访问
					field[j].setAccessible(true);
					System.out.println("filed get 值为:" + field[j].get(model));
					if(typeClass == String.class)
					{
						Constructor con = typeClass.getConstructor(typeClass); 
						Object newvalue = null;
				
						newvalue = con.newInstance("20");  
					}
					else
					{
						field[j].set(model, 20);
					}
					System.out.println("filed set 后值为:" + field[j].get(model));
				
					//使用getMethod方法进行操作。
					//对于private变量,虽然在get时可以不使用getmethod.setAccessible(true)
					//但在setmethod的时候一定要调用setmethod.setAccessible(true)才可以进行修改。
					//另:从效率的角度上考虑,建议在getmethod时调用getmethod.setAccessible(true);
					 System.out.println("方法名为:" + "Get" + name);
					 Method getmethod = model.getClass().getMethod("Get" + name);
					 getmethod.setAccessible(true);
					 System.out.println("getmethod 值为:" + getmethod.invoke(model));
					 
					Method setmethod = model.getClass().getMethod("Set" + name, typeClass);
					setmethod.setAccessible(true);
					if(type.equals("class java.lang.String"))
					 {
						 setmethod.invoke(model, "test1");
					 }
					 else
					 {
						setmethod.invoke(model, 20);
					 }
					 System.out.println("set method 后值为:" + getmethod.invoke(model));
				 }catch(Exception e){
					 e.printStackTrace();
				 }
		 }  
	 }  
	
	public static void main(String[] args)
	{
		try
		{
			TestClass test = new TestClass();
			test.SetA(0);
			test.SetB(21L);
			test.SetC("test");
			reflectTest(test);
			
			System.out.println();
			System.out.println();
			
			TestClass2 test2 = new TestClass2();
			test2.SetA(0);
			test2.SetB(21L);
			test2.SetC("test");
			reflectTest(test2);
		}
		catch(Exception e)
		{
			
		}
	}
}

class TestClass{
	public int GetA() {return a;} 
	public void SetA(int a) {this.a = a;}
	public long GetB() {return b;}
	public void SetB(long b) {this.b = b;}
	public String GetC() {return c;}
	public void SetC(String c) {this.c = c;}
	public double GetE() { return e;}
	public void SetE(double e) {this.e = e;}
	public float GetD() {return d;}
	public void SetD(float d) { this.d = d; }
	
	private int a;
	private long b;
	private String c;
	private double e;
	private float d;
}

class TestClass2{
	public Integer GetA() {return a;} 
	public void SetA(Integer a) {this.a = a;}
	public Long GetB() {return b;}
	public void SetB(Long b) {this.b = b;}
	public String GetC() {return c;}
	public void SetC(String c) {this.c = c;}
	public Double GetE() { return e;}
	public void SetE(Double e) {this.e = e;}
	public Float GetD() {return d;}
	public void SetD(Float d) { this.d = d; }
	
	private Integer a;
	private Long b;
	private String c;
	private Double e;
	private Float d;
}


reflect虽然提供了getter和setter的修改,但从效率上来说要比直接访问getter和setter的效率低,因此在选择是否使用reflect做成员属性的访问修改,可以根据实际情况进行选择。

你可能感兴趣的:(Java的反射reflect使用)