1. 程式人生 > >Java反射機制建立物件

Java反射機制建立物件

package lxf;

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

class Person {
	private String name;
	private int age;

	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public Person() {
		// TODO Auto-generated constructor stub
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

/**
 * 使用反射機制來建立物件
 * 
 * @author lxf
 * @time 2014-4-8下午05:08:41
 * 
 */
public class CreateObject {

	/**
	 * Java的反射機制是指:反射就是把Java類中的各種成分對映成相應相應的Java類, 然後就可以獲取這個類的所有資訊
	 * 
	 * @throws Exception
	 */
	public static void createObj1() throws Exception {
		// 返回與帶有給定字串名的類或介面相關聯的 Class 物件。
		// Class classType = Person.class;
		Class classType = Class.forName("lxf.Person");
		Object obj = classType.newInstance();
		System.out.println("使用反射反射機制創建出來的物件是否是Person類的物件:"
				+ (obj instanceof Person));
	}

	/**
	 * 建立帶有構造引數的物件的時候我們需要使用另外一種方式即: 1.先獲取操作類的Class物件即位元組碼檔案
	 * 2.使用Class物件的getConstructor
	 * (parameterTypes)方法獲取該物件的構造方法的物件,注意括號中可以帶不等的可變引數,
	 * 3.使用構造方法物件的newInstance(initargs)方法就可以例項化一個物件 4.注意,使用這些方法都不可以訪問被
	 * private修飾的方法,需要設定某些訪問許可權setAccessable()方法
	 * 
	 * @throws Exception
	 */
	public static void createObj2() throws Exception {
		@SuppressWarnings("rawtypes")
		Class classType = Person.class;

		@SuppressWarnings("unchecked")
		Constructor<Person> con = classType.getConstructor(String.class,
				int.class);
		Object obj = con.newInstance("lxf", 23);
		System.out.println("使用constructor物件的newInstance方法建立物件的資訊:"
				+ ((Person) obj).getName());
	}

	/**
	 * 操作方法包括(private方法) 步驟: 1.首先獲取要操作類的Class物件
	 * 2.然後通過Class物件的getMethod方法獲取要操作的方法的Method物件(兩個引數,第一個引數是方法名,第二個引數是引數型別)
	 * 3.呼叫Method的方法的invoke方法(兩個引數,第一個引數是該方法屬於的類物件,具體引數)
	 * 4.當方法被private修飾的時候,首先需要呼叫getDeclaredMethod()方法獲取要操作的被private修飾的類。
	 * 在這裡要注意這個getDeclaredMethod方法,它既可以用作獲取普通方法的物件也可以用來操作private修飾的方法,
	 * 但是操作private修飾的方法的時候,必須使用這個方法,其它方法不可以。普通方法還可以使用getMethod方法,
	 * 且屬性操作也是如此。另外,還需要設定訪問許可權setAccessable(true)才可以
	 * 
	 * @throws Exception
	 */
	public static void methodDo() throws Exception {
		Person p = new Person();
		Class classType = Person.class;
		Method method = classType.getMethod("setName", String.class);
		method.invoke(p, "ckl");
		System.out.println("使用反射操作SetName方法後,Person物件的name值是:" + p.getName());

		Method method2 = classType.getDeclaredMethod("test");
		method2.setAccessible(true);
		method2.invoke(p);
	}

	/**
	 * 操作欄位
	 * 
	 * @throws Exception
	 */
	public static void FieldDo() throws Exception {
		Person p = new Person();
		Class classType = Person.class;
		Field field = classType.getDeclaredField("name");
		Field field2 = classType.getDeclaredField("age");
		field.setAccessible(true);
		field2.setAccessible(true);
		field.set(p, "lxf");
		field2.set(p, 23);
		System.out.println("使用反射機制操作被private修飾的物件欄位後得到的屬性值是:" + p.getName());
		System.out.println("使用反射機制操作被private修飾的物件欄位後得到的屬性值是:" + p.getAge());
	}

	public static void main(String[] args) throws Exception {
		new CreateObject().FieldDo();
	}

}

根據以上程式碼:.使用反射機制建立物件的步驟如下:
1、先宣告你要建立的物件的類全稱;使用Class類的靜態方法forName(String.className)載入這個類的位元組碼(注意,載入位元組碼不等於例項化物件) ,返回 一個Class物件,這個物件代表的是一個位元組碼檔案。

2、呼叫這個類物件(位元組碼)的方法newInstance()方法(注意:這裡的這個newInstance方法預設呼叫預設的構造方法即呼叫無參的構造方法, 一旦構造方法有引數時,此方法行不通,需要使用構造方法的物件的相關方法來 例項化)例項化類Person,返回的是Object型別
3、強制轉換成Person型別即你所需型別
而獲得Class物件的方法還有:
Class c = Class.forName("java.lang.String");這條語句得到一個 String 類的類物件。還有另一種方法,如下面的語句:Class c = int.class; 或者 Class c = Integer.TYPE;它們可獲得基本型別的類資訊。其中後一種方法中訪問的是基本型別的封裝類 (如 Integer) 中預先定義好的 TYPE 欄位。
到此反射基本操作就結束了,詳細方法可參看API。