天天看點

Java 反射類--Class

我們先來看反射提供的功能:

反射機制提供功能:加載運作時确定資料類型,解析類結構,擷取内部資訊

操作該類型或執行個體,通路屬性,調用方法,建立新對象

java反射是誰來提供呢?

Class對象提供,但是首先需要通過JVM擷取對象,建立Class對象

建立Class對象有三種方式:

使用Class類的forName()靜态方法如:Class.forName(java.lang.reflect.Field)

調用類的class屬性擷取對應的Class對象,

調用某個對象的getClass()方法

擷取Class對象,就可以得到對象的真實資訊

如:對象的構造函數,屬性,方法,注解,接口,父類,注解(必須是具有源碼,否則注解不能查詢到)等

如:

Constructor<?>getconstructors()傳回class對象辨別的所有public 構造器
Method[] getMethods()
FieldgetField(String name)
Annotation[]getAnnotations()
           

以上方法是有多重載的,可根據參數類型擷取不同如 class.getMethod("info",String.class) 

反射能做什麼?

以上是通過反射擷取對象,取得對象的屬性方法

同時反射還可以生成對象以及操作對象的方法,形成動态代理的基礎,ORM的基礎

建立對象方式

使用Class對象newIntance()建立class對象執行個體,但必須有預設構造器

或使用class對象指定的構造器,再調用newInstance方法,可以建立指定執行個體

 事例

擷取某個對象,并建立該對象調用該對象方法

1 POJO類

public class User {

	
	private String userName;
	private String password;

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}
	
	public User(){
		
	}
	
	public User(String username){
		this.userName=username;
	}
           

2 調用類與執行個體

public static void main(String[] args) throws SecurityException,
			NoSuchFieldException, InstantiationException, IllegalAccessException,
			NoSuchMethodException, ClassNotFoundException {

		getProperty(User.class);//調用
	}

	public static void getProperty(Class<?> entityClass) throws SecurityException,
			NoSuchFieldException, InstantiationException, IllegalAccessException,
			NoSuchMethodException, ClassNotFoundException {

		//-----start----反射擷取對象---------
		String cName = entityClass.getName();
		// 從類的名字中解析出類名
		String userName = cName.substring(cName.lastIndexOf(".") + 1, cName.length());
		System.out.println("實體名稱為:"+ userName);
		// 擷取對象的所有屬性
		Field[] fields = entityClass.getDeclaredFields();

		// 擷取對象的所有方法
		Method[] methods = entityClass.getDeclaredMethods();
		List<String> listfeld = new ArrayList<>();
		for (Field field : fields) {
			System.out.println("屬性名稱有:" + field.getName());

		}
		for (Method method : methods) {
			System.out.println("方法名稱有:" + method.getName());
		}
		
		//-------反射擷取對象-end--------+
		
		//反射建立對象,調用對象方法-------start--------
		User userfroname = (User)	Class.forName(cName).newInstance();        //擷取Class對象方式1 :通過字元串
		User userClass = (User) entityClass.newInstance();                      //擷取Class對象方式2: 通過Class類型
		userClass.setUserName("我的大名是:任秋明---通過class名稱建立對象");
		userfroname.setUserName("我的大名是:任秋明--Class類型建立對象");
		System.out.println(userClass.getUserName());
		System.out.println(userfroname.getUserName());
		//反射建立對象,調用對象方法-------end--------
	}
           

3 測試結果

實體名稱為:User

屬性名稱有:userName

屬性名稱有:password

方法名稱有:getUserName

方法名稱有:setUserName

方法名稱有:setPassword

方法名稱有:getPassword

我的大名是:任秋明---通過class名稱建立對象

我的大名是:任秋明--Class類型建立對象

小結:

 總的來說,java反射機制可以解決一些不靈活的程式,IOC的依賴注入,動态代理,動過名稱反射調用類的方法。但與此同時反射同時也帶來的效率上的問題,凡事都有兩面性,要靈活難免犧牲效率。