1. 程式人生 > >Java之反射

Java之反射

       Java的反射機制,常用的4個類,Class、Field、Constractor、Method。Class是一個比較特殊的類,可以說任何一個類都是Class的例項物件。後面的Field、Constractor、Method三個類都是在java.lang.reflect包下。

在Java中萬事萬物皆物件。

1.Class類的使用

例如有一個類

public class Food{
    public void print(){
		System.out.println("helloworld");
	}
	public void print(int a,int b){
		System.out.println(a+b);
	}
	public void print(String a,String b){
		System.out.println(a.toUpperCase()+","+b.toLowerCase());
	}
}

我們可以用Class來例項Food物件

//一般的常用方法
Food food = new Food();//food就表示出來了.
//Class類的例項物件,如何表示呢
//任何一個類都是Class的例項物件,這個例項物件有三種表示方式

//第一種表示方式--->實際在告訴我們任何一個類都有一個隱含的靜態成員變數class
Class c1 = Food.class;

//第二中表達方式  已經知道該類的物件通過getClass方法
Class c2 = food.getClass();

//第三種表達方式
Class c3 = null;
try {
	 c3 = Class.forName("com.smxy.lq.Food");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
	 e.printStackTrace();
}
//我們完全可以通過類的類型別建立該類的物件例項
Food food = (Food)c1.newInstance();//需要有無引數的構造方法

2.Field的使用

成員變數也是物件

Field類封裝了關於成員變數的操作,通過Class類的 getFields()方法獲取的是所有的public的成員變數的資訊,getDeclaredFields獲取的是該類自己宣告的成員變數的資訊。

    /**
     * 獲取成員變數的資訊
     * @param obj
     */
	public static void printFieldMessage(Object obj) {
		Class c = obj.getClass();
		//Field[] fs = c.getFields();
		Field[] fs = c.getDeclaredFields();
		for (Field field : fs) {
			//得到成員變數的型別的類型別
			Class fieldType = field.getType();
			String typeName = fieldType.getName();
			//得到成員變數的名稱
			String fieldName = field.getName();
			System.out.println(typeName+" "+fieldName);
		}
	}

3.Constractor的使用

建構函式也是物件

java.lang.reflect.Constructor中封裝了建構函式的資訊,通過Class類的getConstructors獲取所有的public的建構函式,getDeclaredConstructors得到所有的建構函式。

	/**
	 * 列印物件的建構函式的資訊
	 * @param obj
	 */
	public static void printConMessage(Object obj) {
		Class c = obj.getClass();
		c.getDeclaredConstructors();
		Constructor[] cs = c.getDeclaredConstructors();
		for (Constructor constructor : cs) {
		
			System.out.print(constructor.getName()+"(");
			//獲取建構函式的引數列表--->得到的是引數列表的類型別
			Class[] paramTypes = constructor.getParameterTypes();
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
			System.out.println(")");
		}
	}

4.Method的使用

一個成員方法就是一個Method物件

Method類封裝了方法物件,通過Class類的getMethods()方法獲取的是所有的public的函式,包括父類繼承而來的,getDeclaredMethods()獲取的是所有該類自己宣告的方法,不問訪問許可權。

	/**
	 * 列印類的資訊(方法資訊)
	 * @param obj 該物件所屬類的資訊
	 */
	public static void printClassMethodMessage(Object obj){
		//要獲取類的資訊  首先要獲取類的類型別
		Class c = obj.getClass();//傳遞的是哪個子類的物件  c就是該子類的類型別
		//獲取類的名稱
		System.out.println("類的名稱是:"+c.getName());
		Method[] ms = c.getDeclaredMethods();//c.getDeclaredMethods()
		for(int i = 0; i < ms.length;i++){
			//得到方法的返回值型別的類型別
			Class returnType = ms[i].getReturnType();
			System.out.print(returnType.getName()+" ");
			//得到方法的名稱
			System.out.print(ms[i].getName()+"(");
			//獲取引數型別--->得到的是引數列表的型別的類型別
			Class[] paramTypes = ms[i].getParameterTypes();
			for (Class class1 : paramTypes) {
				System.out.print(class1.getName()+",");
			}
			System.out.println(")");
		}
	}

利用Method的invoke方法我們可以執行類中的方法。

例如:這樣我們就可以執行類中的toString方法。

		// 1.獲取方法名稱
		String getMethodName = "toString";
		// 2.獲取方法物件
		Class c = obj.getClass();
		try {
			// get方法都是public的且無引數
			Method m = c.getMethod(getMethodName);
			// 3 通過方法的反射操作方法
			Object value = m.invoke(obj);
			return value;
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}