Reflecton

 一、獲取Class對象:
	1、Class.forName()
	2、類.class
	3、對象.getClass()
	注意:同一類型的Class對象是相同的。
	int[] a = new int[10];
	int[] b = new int[100];
	int[][] c = new int[20][23];
	double[] d = new double[123];
	
	a.getClass() == b.getClass()
	a.getClass() != c.getClass()
	a.getClass() != d.getClass()
二:利用反射機制獲得屬性、方法、構造器
	1、利用反射獲得屬性 Field類
		getField() 獲取公共(public)的指定屬性 
		getFields() 獲取公共(public)的所有屬性
		getDeclaredField() 獲取聲明的所有屬性,包括private
		getDeclaredFields()
	2、利用反射獲得方法 Methods類
		getMethod()
		getMethods()
		getDeclaredMethod()
		getDeclaredMethods()
	3、利用反射獲得構造器 Constructor 類
		 getConstructor()
		 getConstructors()
		 getDeclaredConstructor()
		 getDeclaredConstructors()
三:利用反射創建對象,操作方法、操作屬性。
	這三個都可以使用setAccessible(true),來訪問非公共的等構造器、屬性和方法
	1、創建對象
		newInstance() 調用無參構造器來構造對象
		調用有參構造器的操作是現獲得有參構造器,再利用newInstance(參數),來構建對象
	2、操作方法
		invoke()
	3、操作方法
		set()設置屬性值
四:反射機制使用
	1、 使用反射雖然可以使java帶有一定的動態性,但也會降低程序的效率
		在一些情況下使用setAccessile(true),來提高程序效率。這個方法的意思
		是說該構造器、方法、屬性..等是安全的,不用進行安全檢查。這樣既可以提高效率
		又可以利用反射操作一些private..屬性和方法..
	2、使用反射機制讀取註解:
		getAnnocations()// 獲得所有的註解
		getAnnocation()// 獲得指定註解
	3、使用反射機制讀取泛型:
		1、獲得方法參數的泛型getGenericParameterTypes()
		2、獲得方法返回值的泛型getGenericReturnType()
	
一:獲取反射對象的三種方式:
package com.chen.Points;
/**
 * 獲取Class對象
 * 1、Class.forName()
 * 2、類.class
 * 3、對象.getClass()
 * @author Administrator
 *
 */
public class GetClass {

	public static void main(String[] args) throws Exception {
		
		String path = "com.chen.Points.Student";
		// 第一種
		Class clazz1 = Class.forName(path);
		// 第二種
		Class clazz2 = String.class;
		// 第三種
		Class clazz3 = path.getClass();// path是一個字符串對象
		
		// 下面要注意一下:同一種類型生成的Class對象是相同的
		System.out.println(clazz2 == clazz3);// true
		
		int[] a = new int[10];
		int[] b = new int[100];
		int[][] c = new int[20][23];
		double[] d = new double[123];
		// 輸出結果前兩個相同,其他都不相同
		System.out.println(a.getClass().hashCode());
		System.out.println(b.getClass().hashCode());
		// System.out.println(a.getClass() == c.getClass());報錯,非法操作,因爲==兩邊類型不同
		System.out.println(c.getClass().hashCode());
		System.out.println(d.getClass().hashCode());
		
	}
	
}

package com.chen.Points;
/**
 * javabean
 * @author Administrator
 *
 */
public class Student {

	private String name;
	private long id;
	private int age;
	
	public Student() {
		
	}

	public Student(String name, long id, int age) {
		super();
		this.name = name;
		this.id = id;
		this.age = age;
	}

	public String getName() {
		return name;
	}

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

	public long getId() {
		return id;
	}

	public void setId(long id) {
		this.id = id;
	}

	public int getAge() {
		return age;
	}

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

二:用反射獲取操作構造器、方法、屬性
package com.chen.Points;

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

/**
 * 
 * 1、利用反射獲得屬性
 * 2、利用反射獲得方法
 * 3、利用反射獲得構造器
 * 
 * 4、利用反射創建對象
 * 5、利用反射調用方法
 * 6、利用反射訪問屬性
 * @author Administrator
 *
 */
public class Use_Class {

	static String path = "com.chen.Points.Student";
	public static void main(String[] args) throws Exception {
		System.out.println("test01:====================");
		test01();
		System.out.println("test02:=====================");
		test02();
		System.out.println("test03:====================");
		test03();
		System.out.println("test04=====================:");
		test04();
		System.out.println("test05=====================:");
		test05();
		System.out.println("test06=====================:");
		test06();
	}
	
	/**
	 * 獲取屬性
	 * getField() 獲取公共(public)的指定屬性 
	 * getFields() 獲取公共(public)的所有屬性
	 * getDeclaredField() 獲取聲明的所有屬性,包括private
	 * getDeclaredFields()
	 * @throws Exception 
	 */
	public static void test01() throws Exception {
		
		Class<Student> clazz = (Class<Student>) Class.forName(path);
		
		// 獲得所有屬性
		Field[] fields = clazz.getDeclaredFields();
		for(Field temp: fields) {
			
			System.out.println(temp.getName());
		}
		// 獲得指定屬性
		Field f = clazz.getDeclaredField("id");
		System.out.println(f.getName());
		System.out.println(f);

	}
	
	/**
	 * 獲得方法,用法同上
	 * getMethod()
	 * getMethods()
	 * getDeclaredMethod()
	 * getDeclaredMethods()
	 * @throws Exception 
	 */
	public static void test02() throws Exception {

		Class<Student> clazz = (Class<Student>) Class.forName(path);

	}
	
	/**
	 * 獲得構造器,用法同上
	 * getConstructor()
	 * getConstructors()
	 * getDeclaredConstructor()
	 * getDeclaredConstructors()
	 * @throws Exception 
	 */
	public static void test03() throws Exception {
		
		Class<Student> clazz = (Class<Student>) Class.forName(path);
		// 注意一下獲得指定的構造器
		Constructor c = clazz.getDeclaredConstructor(String.class, long.class, int.class);
		System.out.println(c);
		
	}
	/**
	 * 利用反射構建對象
	 * newInstance()
	 * setAccessible()可以用來操作private、protected、default等構造器
	 * @throws Exception 
	 */
	public static void test04() throws Exception {
		
			Class<Student> clazz = (Class<Student>) Class.forName(path);
			
			// 調用無參構造器構建對象
			Student stu = clazz.newInstance();
			System.out.println(stu.getAge());
			// 調用有參構造器構建對象
			Constructor<Student> c = clazz.getDeclaredConstructor(String.class, long.class, int.class);
			Student stu2 = c.newInstance("CHJ", 31212, 22);
			System.out.println(stu2.getAge());
			
	}
	
	/**
	 * 用反射調用方法
	 * invoke()
	 * setAccessible()可以用來操作private、protected、default等方法
	 * @throws Exception 
	 */
	public static void test05() throws Exception {
		
		Class<Student> clazz = (Class<Student>) Class.forName(path);
		Constructor<Student> c = clazz.getDeclaredConstructor(String.class, long.class, int.class);
		Student stu2 = c.newInstance("CHJ", 31212, 22);
		System.out.println(stu2.getName());
		// 用反射來調用setName()方法
		Method method = clazz.getDeclaredMethod("setName", String.class);// 沒有參數就是null
		method.invoke(stu2, "陳虹君");
		System.out.println(stu2.getName());

		
	}
	
	/**
	 * 用反射操作屬性
	 * setAccessible()可以用來操作private、protected、default等屬性
	 * @throws Exception 
	 */
	public static void test06() throws Exception {
		
		Class<Student> clazz = (Class<Student>) Class.forName(path);
		Constructor<Student> c = clazz.getDeclaredConstructor(String.class, long.class, int.class);
		Student stu2 = c.newInstance("CHJ", 31212, 22);
		System.out.println(stu2.getName());
		
		Field f = clazz.getDeclaredField("name");
		// 意思是:這個屬性不需要安全檢查,可以直接訪問
		f.setAccessible(true);// 如果缺省就會報錯,因爲name屬性是私有變量,外部類無法操作
		f.set(stu2, "laochen");
		System.out.println(stu2.getName());
		
	}
}


發佈了44 篇原創文章 · 獲贊 9 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章