1. 程式人生 > >菜鳥先飛之JAVA_反射

菜鳥先飛之JAVA_反射

反射的概述 JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。要想解剖一個類,必須先要獲取到該類的位元組碼檔案物件。而解剖使用的就是Class類中的方法,所以先要獲取到每一個位元組碼檔案對應的Class型別的物件。 獲取Class物件的三種方式: 1、Object類的getClass()方法 2、靜態屬性class 3、Class類中靜態方法forName()方法


Class類中的成員方法 public static Class<?> forName(String className) throws ClassNotFoundException;返回與帶有給定字串名的類或介面相關聯的 Class 物件。
public class Demo_Reflect {

	/**
	 * @param args
	 * @throws ClassNotFoundException 
	 * 通過反射獲取class物件
	 */
	public static void main(String[] args) throws ClassNotFoundException {
		
		//Object類的getClass方法
		Person p = new Person();
		Class clazz1 = p.getClass();		

		//靜態屬性class		
		Class clazz2 = Person.class;
		
		//Class類中靜態方法forName()方法
		Class clazz1 = Class.forName("java.study.bean.Person");
		
		System.out.println(clazz1 == clazz2);
		System.out.println(clazz2 == clazz3);
	}

}


public T newInstance() throws InstantiationException,IllegalAccessException;建立此 Class 物件所表示的類的一個新例項。如同用一個帶有一個空引數列表的 new 表示式例項化該類。如果該類尚未初始化,則初始化這個類。 public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException返回一個 Constructor 物件,它反映此 Class 物件所表示的類的指定公共構造方法。parameterTypes 引數是 Class 物件的一個數組,這些 Class 物件按宣告順序標識構造方法的形參型別。
public class Demo3_Constructor {

	/**
	 * @throws Exception 
	 * 通過反射獲取建構函式
	 */
	public static void main(String[] args) throws Exception {
		
		Class clazz = Class.forName("java.study.bean.Person");
		//通過無參構造建立物件
		Person p = (Person) clazz.newInstance();				

		//獲取有參構造
		Constructor c = clazz.getConstructor(String.class,int.class);	
		//通過有參構造建立物件
		Person p = (Person) c.newInstance("張三",23);						

	}

}


public Field getField(String name) throws NoSuchFieldException,SecurityException;返回一個 Field 物件,它反映此 Class 物件所表示的類或介面的指定公共成員欄位。 public Field getDeclaredField(String name) throws NoSuchFieldException, SecurityException返回一個 Field 物件,該物件反映此 Class 物件所表示的類或介面的指定已宣告欄位。name 引數是一個 String,它指定所需欄位的簡稱。注意,此方法不反映陣列類的 length 欄位。 public void set(Object obj,Object value) throws IllegalArgumentException, IllegalAccessException將指定物件變數上此 Field 物件表示的欄位設定為指定的新值。 public void setAccessible(boolean flag)throws SecurityException將此物件的 accessible 標誌設定為指示的布林值。值為 true 則指示反射的物件在使用時應該取消 Java 語言訪問檢查。值為 false 則指示反射的物件應該實施 Java 語言訪問檢查。
public class Demo4_Field {

	/**
	 * @throws Exception
	 * 通過反射獲取成員變數
	 */
	public static void main(String[] args) throws Exception {
		Class clazz = Class.forName("java.study.bean.Person");
		//獲取有參構造
		Constructor c = clazz.getConstructor(String.class,int.class);
		//通過有參構造建立物件	
		Person p = (Person) c.newInstance("張三",23);						
		
		//獲取姓名欄位
		//Field f = clazz.getField("name");								
		//修改姓名的值
		//f.set(p, "李四");	//由於name欄位是私有的,所以會報錯											
		//暴力反射獲取欄位
		Field f = clazz.getDeclaredField("name");
		//去除私有許可權						
		f.setAccessible(true);												//修改姓名的值
		f.set(p, "李四");	
		
		System.out.println(p);
	}

}


public Method getMethod(String name,Class<?>... parameterTypes) throws NoSuchMethodException,SecurityException返回一個 Method 物件,它反映此 Class 物件所表示的類或介面的指定公共成員方法。 public Object invoke(Object obj,Object... args)throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;對帶有指定引數的指定物件呼叫由此 Method 物件表示的底層方法。個別引數被自動解包,以便與基本形參相匹配,基本引數和引用引數都隨需服從方法呼叫轉換。
public class Demo5_Method {

	/**
	 * @throws Exception 
	 * 通過反射獲取方法
	 */
	public static void main(String[] args) throws Exception {
		Class clazz = Class.forName("java.study.bean.Person");
		//獲取有參構造
		Constructor c = clazz.getConstructor(String.class,int.class);	
		//通過有參構造建立物件
		Person p = (Person) c.newInstance("張三",23);						
		
		//獲取有參的setName方法		
		Method m2 = clazz.getMethod("setName", String.class);	
		//呼叫該方法		
		m2.invoke(p, "李四");
	}

}