java中的反射機制淺析
Java中,反射是一種強大的工具,它允許執行中的java程式對自身進行檢查,並能直接操作程式的內部屬性。反射允許我們執行的時候使程式碼直接裝載到JVM中類的內部資訊。所以想要構建靈活的應用,反射必不可少。 這裡我將根據物件導向設計的方式來寫一個小demo,根據反射來載入不同的類,使系統具有比較好的擴充套件性。
首先設計一個介面:
package cc.hao.reflect;
import java.util.List;
public interface Action {
public List<String> act(List<String> params);
}
接下來為不同的功能編寫不同的類,繼承Action介面,針對介面程式設計。
//Store類
package cc.hao.reflect;
import java.util.ArrayList;
import java.util.List;
public class Store implements Action{
@Override
public List<String> act(List<String> params) {
List<String> result = new ArrayList<>();
result.add("this is store");
return result;
}
}
//Load類
package cc.hao.reflect;
import java.util.ArrayList;
import java.util.List;
public class Load implements Action{
@Override
public List<String> act(List<String> params) {
List<String> result = new ArrayList<>();
result.add("this is load");
return result;
}
}
... 我們會需要編寫很多的類,每次具體化哪個類呢?如果向程式傳遞一個引數,然後讓它去自行例項化,執行它的act()方法,那就可以避免以後的麻煩了。
利用反射,一切都迎刃而解。
首先編寫配置檔案:emp.properties
100=Load
200=Search
300=Store
然後我們利用反射來進行動態載入呼叫
package cc.hao.reflect;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
public class DynamicLoad {
//這段程式碼用來載入配置檔案,查詢出需要的類名
Public String loadProp(String head) throws IOException{
String result = null;
Properties prop = new Properties();
FileInputStream fis = new FileInputStream("emp.properties");
prop.load(fis);
result = prop.getProperty(head);
fis.close();
return result;
}
//用反射找出需要呼叫的類,發揮了面向介面程式設計的用處
@SuppressWarnings({ "unchecked", "rawtypes" })
public String loadClass(String head,String content) throws Exception{
String result = null;
String s = "cc.hao.reflect." + this.loadProp(head);
Class className = Class.forName(s);
Action action = (Action) className.newInstance();
Class[] params = new Class[1];
params[0] = Class.forName("java.util.List");
Method method = className.getMethod("act",params);
Object[] args = new Object[1];
List<String> array = new ArrayList<>();
array.add(content);
args[0] = array;
Object returnObject = method.invoke(action, args);
System.out.println(returnObject);
return result;
}
public static void main(String[] args) throws Exception {
DynamicLoad reflect = new DynamicLoad();
reflect.loadClass(args[0], "");
}
}
測試結果:
Java DynamicLoad 100 | [this is load]
Java DynamicLoad 200 | [this is search]
接下來我們再來看一段程式碼:
package cc.hao.reflection;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class TestReflect {
public Object copy(Object obj) throws Exception{
Class<?> clazz = obj.getClass();
System.out.println("Class:" + clazz.getName());
Object objCopy = clazz.getConstructor(new Class[]{}).newInstance();
Field[] fields = clazz.getDeclaredFields();
}
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
String fieldName = field.getName();
String firstLetter = fieldName.substring(0,1).toUpperCase();
String getMethodName = "get" + firstLetter + fieldName.substring(1);
String setMethodName = "set" + firstLetter + fieldName.substring(1);
Method getMethod = clazz.getMethod(getMethodName,new Class[]{} );
Method setMethod = clazz.getMethod(setMethodName, new Class[]{field.getType()});
Object value = getMethod.invoke(obj, new Object[]{});
System.out.println(fieldName + ":" + value);
setMethod.invoke(objCopy, new Object[]{value});
}
return objCopy;
}
public static void main(String[] args) throws Exception {
Customer customer = new Customer("liuyu",20);
customer.setId(30);
Customer customerCopy = (Customer) new TestReflect().copy(customer);
System.out.println(customerCopy);
}
}
class Customer{
private int id;
private String name;
private int age;
public Customer() {
}
public Customer(String name, int age) {
super();
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
這裡我們通過反射來複制一個Customer物件。我建議您認真閱讀關於涉及到的API的文件,著重理解
Object objCopy = clazz.getConstructor(new Class[]{}).newInstance();
Method setMethod = clazz.getMethod(setMethodName, new Class[]{field.getType()});
裡的引數含義,這裡就不在多說了。
對於反射一直是很多人不甚理解的地方,參考了一些網上的文章,希望通過一些簡單的例子引導您加深對反射的認識,寫的比較膚淺,不對之處還請您指正。
相關文章
- 淺析JAVA反射Java反射
- 淺析Java反射--JavaJava反射
- Java 中的 反射機制Java反射
- 淺談Java的反射機制和作用Java反射
- Java中的類反射機制Java反射
- 淺析Vue 中 $nextTick 機制Vue
- 關於Java中的反射機制Java反射
- Java的反射機制Java反射
- 淺析java記憶體管理機制Java記憶體
- Java反射機制Java反射
- MVVM機制淺析MVVM
- 淺談java中的反射Java反射
- Java核心反射機制Java反射
- java利器——反射機制Java反射
- Libco Hook 機制淺析Hook
- Java反射機制簡答Java反射
- Java反射機制那些事Java反射
- 淺析雙親委派機制
- NX實現機制淺析
- Timer機制原始碼淺析原始碼
- PostgreSQL MVCC快照機制淺析SQLMVC
- js執行機制淺析JS
- android中反射機制Android反射
- Java 反射機制的三種方式Java反射
- java反射機制的學習心得Java反射
- JavaScript的事件迴圈機制淺析JavaScript事件
- 淺析JavaScript的事件迴圈機制JavaScript事件
- 淺析java中的IO流Java
- Java註解與反射機制Java反射
- java進階(41)--反射機制Java反射
- Java筆記-反射機制(一)Java筆記反射
- 淺析注意力(Attention)機制
- 微前端無界機制淺析前端
- Linux系統呼叫機制淺析Linux
- Webpack 模組打包機制淺析Web
- 淺析 PHP7 的垃圾回收機制PHP
- 淺析Dubbo的SPI擴充套件機制套件
- TFTP反射放大攻擊淺析FTP反射
- java中的JAR檔案淺析JavaJAR