Java 反射類--Class,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的依賴注入,動態代理,動過名稱反射調用類的方法。但與此同時反射同時也帶來的效率上的問題,凡事都有兩面性,要靈活難免犧牲效率。