2017年6月29日 星期四

Java:Reflection映射

在java裡有個技術叫做Reflection,能夠在程式執行期間得知自己的外觀長相,並自我修改,甚至至我複製,未使用Reflection的程式碼,物件所需類別無法在執行時再決定,靈活度相對較低,但是使用reflction機制可破壞原有程式碼的封裝機制,它的動態讓程式碼不需寫死,能夠更彈性的執行程式。

Reflection機制透過Class的Object,可以描述每個類別的相關資訊,包括隸屬哪個Package,類別本身的修飾詞,繼承自誰,成員變數以及方法,除了描述相關資訊外,還提供你可以透過它來來進行操作。


public class Employee {
	private int id;
	private String name;
	private String address;
	
	public Employee() {
		
	}
	
	public Employee(int id, String name,String address) {
		super();
		this.id = id;
		this.name = name;
		this.address=address;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	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;
	}
	
	
}

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

public class Main {
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Class c = Employee.class;

		Field[] fields = c.getDeclaredFields();                   //取得Employee裡的成員變數
		
		Constructor con = c.getDeclaredConstructors()[1];         //取得Employee裡有參數的建構子
		
		System.out.println(Modifier.toString(c.getModifiers()));  //列印出class:Employee的修飾詞,也就是public
		System.out.println(c.getName());                          //列印出class:Employee的名稱
		
		try {
			Object o = con.newInstance(1,"Mary","高雄");    //形成物件

			//Field成員變數的實做
			Field fieldName = c.getDeclaredField("name");  //取得Employee裡的成員變數name
			fieldName.setAccessible(true);         //利用reflection機制把private改成public
			System.out.println(fieldName.get(o));  //印出物件o的name,也就是印出Mary
			fieldName.set(o, "Tom");               //把物件o裡的name,從Mary改成Tom
			System.out.println(fieldName.get(o));  //印出物件o的name,變成了Tom

			//方法的實做
			Method method = c.getMethod("getName", null);  //取得Employee裡的getName方法
			System.out.println(method.invoke(o, null));    //執行getName的方法,印出Tom

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} 
		
	}

}
執行結果:
public
Employee
Mary
Tom
Tom

沒有留言:

張貼留言