java 反射
- 软件开发
- 2022-07-25
- 12热度
- 0评论
反射就是根据类的字节码 class 文件获取一个类的细节,包括构建出来,通过对象去调用方法,访问属性。
生活中的反射:听声辨人
为什么要用反射
- 可将要创建的对象,要调用的方法写到配置文件,然后通过反射来完成方法调用,从而降低代码的耦合性
- 基本上任何一个框架设计都会用到反射,很重要。
反射调用方法的实现步骤:
1、获取类的字节码
2、通过字节码去创建对象
3、反射得到要调用的方法对象method
4、通过反射调用方法
src/main/resources/test.xml
<?xml version="1.0" encoding="UTF-8" ?>
<students>
<student number="001">
<Name>张三</Name>
<Age>18</Age>
<Sex>男</Sex>
</student>
<student number="002">
<Name>李四</Name>
<Age>19</Age>
<Sex>女</Sex>
</student>
<student number="003">
<Name>王五</Name>
<Age>20</Age>
<Sex>未知</Sex>
</student>
</students>
package com.zhuchun.stu;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.File;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* @Auther: zhuchun92@163.com
* @Date: 2020年03月26日 0:59
*/
public class TestReflect {
public static void main(String[] args) throws Exception {
/*
反射调用方法的实现步骤:
1、获取类的字节码
2、通过字节码去创建对象
3、反射得到要调用的方法对象method
4、通过反射调用方法
*/
// 获取类的字节码
// 方式一:
Class<Student> studentClass = Student.class;
// 方式二:
Class<Student> studentClass1 = (Class<Student>) Class.forName("com.zhuchun.stu.Student");
// 通过字节码调用newInstance方法创建对象,底层其实是调用字节码对应类中的默认构造函数
Student student = studentClass.newInstance();
// 通过反射获取该类所有 public 方法
Method[] methods = studentClass.getMethods(); // 获取当前类中的所有 public 方法
for (Method me : methods){
System.out.println(me.getName()); // 打印该类中所有 public 方法
}
// 通过反射获取我们要调用的方法
Method method = studentClass.getMethod("setName", String.class);
// 通过反射,完成方法调用
method.invoke(student,"张三");
// 通过 getName ,得到数据
Method method1 = studentClass.getMethod("getName");
Object nameobj = method1.invoke(student);
String name = nameobj.toString();
System.out.println("通过反射获取到的name为:"+ name);
String path = "src/main/resources/test.xml";
List<Student> students = parseXML(path);
for (Student stu : students){
System.out.println(stu);
}
}
public static List<Student> parseXML(String path) throws Exception {
// 应用场景:通过 test.xml 文件中的标签来获取得到student对象,
// 原来是通过 解析xml文件,读取element标签名来获取对象属性,如果标签名发生变更则需要变更很多代码,
// 所以可以通过 java 反射来解决此问题
// 如下示例:
SAXReader saxReader = new SAXReader();//创建解析器对象 SAXReader
Document document = saxReader.read(new File(path));// 获取 document 对象
Element rootElement = document.getRootElement();// 获取根元素
List<Element> studentElements = rootElement.elements("student"); // 返回是个 List 集合
List<Student> students = new ArrayList<Student>(); // 用来接收新创建的 student 对象
Class<Student> studentClass2 = Student.class; // 获取类的字节码
// 通过循环处理三个 student 元素
for (Element studentElement : studentElements){
List<Element> elements = studentElement.elements(); // 获取 student 中的各元素标签
Student student1 = studentClass2.newInstance();
for (Element element : elements) { // 遍历 student 中的各标签
String nameElement = element.getName(); // 获取标签名称
nameElement = "set"+nameElement;
Method method2 = studentClass2.getMethod(nameElement,String.class); //
method2.invoke(student1,element.getText());
}
students.add(student1);
}
return students;
}
}