Java反射通過父類物件呼叫子類的方法
阿新 • • 發佈:2019-02-01
在做網站開發的時候我們都會寫一個控制器,控制器的作用就是接收客戶端的請求,有時候為了控制訪問入口的唯一性,方便我們監控使用者訪問的資料;最近在抽時間寫一個底層轉發控制器請求的工具,說通俗一點就是首先我定義一個抽象類或者介面A(實現類A就標識為控制器),然後定義很多繼承或者實現了A類的類B(使用者真正的Controller);
1.定義一個抽象類作為所有控制器的父類
package thread;
public abstract class A<T> {
public String[] getRequireParams() {
return new String[] {};
}
public String[] getOptionalParams() {
return new String[] {};
}
public abstract T fly(String param);
}
2.定義子類B
package thread;
public class B extends A<String>{
public String[] getRequireParams() {
return new String[] {"a","b"};
}
public String[] getOptionalParams() {
return new String[] {"c"};
}
@Override
public String fly(String param) {
return "B類被呼叫";
}
}
3.定義子類B1
package thread;
public class B1 extends A<String>{
@Override
public String fly(String param) {
return "B1類被呼叫" ;
}
}
4.定義統一接收使用者請求的controller類,下面就使用main方法模擬控制器
package thread;
import org.apache.commons.lang3.StringUtils;
public class DataHandler{
public static void main(String[] args) {
try {
//模擬控制器接收到的請求類的url
String action = "thread.B";
// String action = "thread.B1";
Class clazz = Class.forName(action);
A obj = (A)clazz.newInstance();
//介面必填引數
String[] requiredParams = obj.getRequireParams();
System.out.println(StringUtils.join(requiredParams));
//介面可選引數
String[] optionalParams = obj.getOptionalParams();
System.out.println(StringUtils.join(optionalParams));
//呼叫介面的具體執行方法,並返回值
Object result = obj.fly("sd");
System.out.println(result);
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
5.執行結果是
ab
c
B類被呼叫
說明:第4步中是通過模擬我們從控制器中獲取到的請求資訊,從資訊中解析出具體類的全路徑,然後通過反射的方式獲取例項物件,因為這些例項物件A類的子類,所以我們把他們統一強轉成A物件,但是根據多型的原理我們知道他們指向記憶體中的例項還是原來的物件。