天天看點

通過模拟Mybatis的自動封裝來了解反射什麼是反射

Java反射入門

  • 什麼是反射
    • 用new關鍵字建立對象
    • 使用反射建立對象
    • 使用反射動态調用方法
    • 總結

什麼是反射

JAVA反射機制是在運作狀态中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意方法和屬性;這種動态擷取資訊以及動态調用對象方法的功能稱為java語言的反射機制

以上就是對反射的解釋,但是解釋的太官方,現在我們從代碼入手。先看不用反射的情況應該怎麼建立對象

用new關鍵字建立對象

比如現在通過JDBC查詢出來了一個結果集ResultSet,需要将結果集轉化成對象之後傳回。

Student student = new Student();
student.setName(resultSet.getString("name"));
return student;
           

這樣寫沒什麼問題,可是如果查詢另外一個實體,這個地方就是“死”的了,隻能再寫類似的代碼,将Student換成Teacher,能不能通過某種形式将建立對象和調用方法的過程動态化呢?很顯然,使用new關鍵字的話不能動态執行個體化,而反射就能做到這一點

使用反射建立對象

現在通過反射的方式,傳入字元串形式的參數,通過這個字元串進行執行個體化

Class<?> cls = Class.forName("com.jack.reflect.Student");
Object object = cls.newInstance();
           

這樣就可以通過com.jack.reflect.Student這個字元串作為變量,進行執行個體化了,列印看一下

通過模拟Mybatis的自動封裝來了解反射什麼是反射

和用new關鍵字效果相同,這就是反射的第一步!!

那麼第二步,可以動态建立對象,肯定也可以動态調用方法,執行個體化的是A類就調用A類的方法,執行個體化的是B類就調用B類的方法,這樣一來,代碼就變得非常非常靈活了!開始上代碼

使用反射動态調用方法

這裡我們來模拟一下Mybatis,用過Mybatis的都知道,它可以幫我們自動封裝好實體類然後傳回,那讓我們來自己模拟實作一下。

//1.使用集合模拟jdbc查詢的resultSet
Map resultSet = new HashMap<String,String>();
resultSet.put("name", "張三");
resultSet.put("age", "21");

//2.動态加載對象,這裡的動态可以了解喂配置檔案    
Class<?> cls = Class.forName("com.jack.reflect.Student");
Object object = cls.newInstance();

//3.通過反射擷取該對象的方法,擷取的是一個集合
Method[] methods = cls.getMethods();

//4.擷取結果集的keySet
Set<String> set = resultSet.keySet();
Iterator<String> iterator = set.iterator();

//疊代“結果集”
while (iterator.hasNext()) {
	//擷取結果集中的“字段”
    String next = iterator.next();
    //将每一個結果集的屬性拼接成setXxxx的形式,比如name就變成setName
    String methodName = Util.toBeSet(next);
    //周遊方法集中的每一個方法
    for (Method method :
            methods) {
        //如果該類的方法中有這個methodName,通過反射調用進行指派,可以了解為調用和methodName這個字元串“長得一樣”的方法
        if (methodName.equals(method.getName())) {
        	/*比如這裡通過反射擷取到的方法集合中有一個setName()方法,結果集中有一個name字段,
        	通過Util.toBeSet()這個方法将name字段變為“setName”這一字元串,
        	那麼比對到之後就可以通過反射的invoke方法調用真正的setName()方法*/
            method.invoke(object,resultSet.get(next));
        }
    }
}

System.out.println(object);

           

Util.toBeSet().java

/**
 * @author Jinkang He
 * @version 1.0
 * @date 2020/7/27 9:10
 */

public class Util {
    public static String toBeSet(String str) {
        String result = null;
        String substring = str.substring(0, 1);
        String s = substring.toUpperCase();
        result = "set" + s + str.substring(1,str.length());
        return result;
    }
}
           

運作看一下效果

通過模拟Mybatis的自動封裝來了解反射什麼是反射

可以看到我們沒有寫死代碼,隻要通過配置檔案或者其他方式讀取到需要封裝的全限定名,就可以給任何遵循了JavaBean規範的實體類進行屬性的自動裝配了

總結

如果讓我用一句話來總結反射的話,那麼就是使用字元串的形式來動态建立對象,擷取屬性,調用方法,這也就是開頭反射定義裡面的運作狀态中,架構之是以可以給任何人使用都利用了反射來支撐,因為架構的開發者不知道你會寫什麼,隻能在你寫好之後使用反射的機制進行動态操作。

本人能力有限,文章中若有遺落或有錯誤,歡迎大家指出糾正,共同交流進步。