1、概念說明java
java的反射機制,是在運行狀態下,能夠動態獲取任意一個類的屬性和方法;能夠動態調用一個對象任意方法;spring
2、反射相關類jvm
java.lang.Class; //類 java.lang.reflect.Constructor;//構造方法 java.lang.reflect.Field; //類的成員變量 java.lang.reflect.Method;//類的方法 java.lang.reflect.Modifier;//訪問權限
3、應用場景性能
1.獲取對象及成員變量this
package com.reflect.dto對象
public class RequestDTO{字符串
private String userId;get
private String userName;io
}class
調用:
Class classz=Class.forName("com.reflect.dto.RequestDTO");
Object obj=classz.newInstance();
if(classz instance of RequestDTO){
RequestDTO requestDTO=(RequestDTO )obj;
}
Field field=classz.getField("userName");
field.set(requestDTO,"ZHANGSAN");
2.經過反射運行配置文件內容
(1)resource.properties
className=com.reflect.dto.RequestDTO
methodName=getUserId
(2)解析配置文件
public static String getValue(String key){
Properties pro=new Properties();
FileReader in=new FileReader("resource.properties");
pro.load(in);
in.close();
return pro.getProperty(key);
}
(3)調用
Class classz =Class.forName(getValue("className"));//獲取類
Object obj=classz.getConstructor().newInstance();//實例化對象
Method method=classz.getMethod(getValue("methodName"));//獲取方法
method.invoke(obj);//調用方法
3.經過反射跳過泛型檢查(在一個String的ArrayList中存儲一個Integer的值方法)
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("張三");
Class classz=arrayList.getClass();
Method m=classz.getMethod("add",Object.class);
m.invoke(arrayList,100);
遍歷打印出來,後就是:
張三
100
4.經過反射獲取對象中註解
package com.annotation
@MyClassAnnotation(desc = "The class", uri = "com.test.annotation.Test")
public class TestAnnotation{
@MyMethodAnnotation(desc = "The class method", uri = "com.test.annotation.Test#setId") public void setId(String id) { System.out.println(" method info: "+id); this.id = id; }
}
Class classz =Class.forName("com.annotation.TestAnnotation");
MyClassAnnotation myClassAnnotation=classz.getAnnotation(MyClassAnnotation.class);
myClassAnnotation.desc();
Method m=classz.getMethod("setId",new Class[]{int.class});
MyMethodAnnotation myMethodAnnotation=m..getAnnotation(MyMethodAnnotation .class);
myMethodAnnotation.desc();
5.spring ioc反射機制原理
<bean id="courseDao" class="com.qcjy.learning.Dao.impl.CourseDaoImpl"></bean>
下面是Spring經過配置進行實例化對象,並放到容器中的僞代碼:
//解析<bean .../>元素的id屬性獲得該字符串值爲「courseDao」
String idStr = "courseDao";
//解析<bean .../>元素的class屬性獲得該字符串值爲「com.qcjy.learning.Dao.impl.CourseDaoImpl」
String classStr = "com.qcjy.learning.Dao.impl.CourseDaoImpl";
//利用反射知識,經過classStr獲取Class類對象
Class<?> cls = Class.forName(classStr);
//實例化對象
Object obj = cls.newInstance();
//container表示Spring容器
container.put(idStr, obj);
4、缺點
性能是一個問題,反射至關於一系列解釋操做,通知jvm要作的事情,性能比直接的java代碼要慢不少。