天天看點

【Android開發經驗】使用反射,得到的類的字段、方法、并實作了簡單的調用

本文後推出Android的ICO架構做準備,是以,假設你想要一個最近的一項研究Android的ICO學生架構。你可以稍微看一下。

首先,簡介一下Java裡面的反射。

JAVA反射機制是在執行狀态中,對于随意一個類,都可以知道這個類的全部屬性和方法。對于随意一個對象,都可以調用它的随意一個方法和屬性。這樣的動态擷取的資訊以及動态調用對象的方法的功能稱為java語言的反射機制。

不知道這種一段解釋,你是否能看懂。假設更簡單的說。反射就是能夠依據你給出類名執行個體化出一個實實在在的對象。是以,對象的執行個體化就不是寫死的了。我們能夠依據傳入的類名不同,進而能夠執行個體化出不同的對象。這種方式能夠和工廠設計模式非常好的結合,進而能夠更加靈活的建立對象。

以下。我們簡單的介紹一下怎樣使用反射來進行對象的創,以及方法、字段的擷取與使用。

首先,給出要用的實體類的代碼,重點注意一下字段和方法的權限的修飾符

package edu.qust.demo;

/**
 * 
 * @ClassName: Person
 * @Description: Person實體類
 * @author: ZhaoKaiQiang
 * @time: 2014-7-18上午10:41:23
 * @version: V1.0
 */
public class Person {

	private int age;
	private String name;
	protected int height;
	public String school;

	Person(){
		this.name = "Person";
		age = 22;
	}
	
	Person(String name) {
		this.name = name;
	}

	private String showName(String _name) {
		return "My name is " + _name;
	}

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

	public int getAge() {
		return age;
	}

	@Override
	public String toString() {
		return "My name is " + name + ", i'm " + age + " years old";
	}
}      

以下,我們開始介紹。在Java中,怎樣使用代碼實作反射。

以下是測試程式

package edu.qust.demo;

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

public class Main {

	private static Person person;
	private static Class<Person> cls;

	@SuppressWarnings("unchecked")
	public static void main(String[] args) {

		person = new Person("Zhao");
		cls = (Class<Person>) person.getClass();

		creatClassByReflection();
		printAllMethods();
		printAllFileds();
		invokePrivateMothod();
	}

	/**
	 * 利用反射建立對象
	 */
	private static void creatClassByReflection() {
		try {
			Person accpTeacher = (Person) Class.forName("edu.qust.demo.Person")
					.newInstance();
			System.out.println(accpTeacher.toString());
			System.out.println();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 擷取并調用私有方法
	 */
	private static void invokePrivateMothod() {
		try {
			// 擷取方法名為showName,參數為String類型的方法
			Method method = cls.getDeclaredMethod("showName", String.class);
			// 若調用私有方法。必須抑制java對權限的檢查
			method.setAccessible(true);
			// 使用invoke調用方法。而且擷取方法的傳回值。須要傳入一個方法所在類的對象,new Object[]
			// {"Kai"}是須要傳入的參數,與上面的String.class相相應
			String string = (String) method.invoke(person,
					new Object[] { "Kai" });
			System.out.println(string);
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 擷取并列印全部的字段名
	 */
	private static void printAllFileds() {
		Field[] field = cls.getDeclaredFields();
		System.out.println("getFields():擷取全部權限修飾符修飾的字段");
		for (Field f : field) {
			System.out.println("Field Name = " + f.getName());
		}
		System.out.println();
	}

	/**
	 * 擷取并列印全部的方法名
	 */
	private static void printAllMethods() {
		Method[] method = cls.getDeclaredMethods();
		System.out.println("getDeclaredMethods():擷取全部的權限修飾符修飾的Method");
		for (Method m : method) {
			System.out.println("Method Name = " + m.getName());
		}
		System.out.println();
	}
}
      

以下是上面的測試程式的輸出結果

My name is Person, i'm 22 years old

getDeclaredMethods():擷取全部的權限修飾符修飾的Method
Method Name = toString
Method Name = showName
Method Name = setAge
Method Name = getAge

getFields():擷取全部權限修飾符修飾的字段
Field Name = age
Field Name = name
Field Name = height
Field Name = school

My name is Kai
      

在java.lang.reflect包中,提供了類和接口,來獲得關于類和對象的反射資訊。

【Android開發經驗】使用反射,得到的類的字段、方法、并實作了簡單的調用

在這裡,我們眼下僅僅關注Field和Method這兩個類,分别代表類的成員變量和方法。

除此之外。在java.lang.Class。還有個反射須要用到的非常重要的類,Class,這個類中封裝了一個類全部的資訊,包含各種全縣修飾符修飾的成員變量和方法。是以,我們能夠用這個類,來擷取類的各種資訊。Class繼承自Object,利用Object.getClass能夠擷取到某對象執行時類的 Class 對象。

我們的操作,主要就是擷取某個類的Class對象。然後利用這個對象,就能夠擷取到某個類全部的成員變量以及方法,而且能夠對随意權限修飾符修飾的方法進行調用,注意。是随意哦,即使是private修飾的類的方法。我們也能夠利用反射進行調用,是以說反射能夠說是相當逆天啊。

首先看第一個方法的輸出

My name is Person, i'm 22 years old

在這裡,我們利用一個類的String字元串的名字,執行個體化出了一個對象。這就是上面所說的。依據傳入的字元串的不同,能夠建立出不同的對象。

調用newInstance方法,Java會去找預設的構造函數,完畢對象的初始化,是以得到了這種結果。

再看第二個方法的輸出

getDeclaredMethods():擷取全部的權限修飾符修飾的Method

Method Name = toString

Method Name = showName

Method Name = setAge

Method Name = getAge

我們使用getDeclaredMethods這種方法,擷取到了類裡面全部的方法,然後我們進行周遊,将類名進行簡單的輸出。

第三個方法的結果和第二個差點兒相同,僅僅隻是就是把Method換成了Filed,然後把字段名進行了輸出。

getFields():擷取全部權限修飾符修飾的字段

Field Name = age

Field Name = name

Field Name = height

Field Name = school

第四個方法中,我們依據方法名,擷取到詳細某一個方法,然後傳入參數。利用invoke進行方法的調用。

再調用之前,必須設定method.setAccessible(true);進而能夠調用使用private修飾的方法。

除了上面代碼中,用到的這些方法,Class類還有非常多其它的方法。很多其它詳細的使用,還是看文檔去吧。

版權聲明:本文部落格原創文章,部落格,未經同意,不得轉載。