• java之反射


    什么是反射?

    反射就是根据类的字节码class文件获取一个类的细节,包括构建出来,通过对象去调用方法,访问属性。

    为什么使用反射?

    可以将要创建的对象,要调用的方法写到配置文件,然后通过反射来完成方法调用,从而降低了代码的耦合性。

    反射调用方法实现步骤

    1.获取类的字节码

    class clazz = Student.class;

    2.通过字节码去创建对象

    //通过字节码调用newlnstance方法创建对象,其实底层是调用的是字节码对应类中默认构造函数

    Student student = clazz.newlnstance();  //获取类的字节码时已经指定了类型,在这就不需要强制转换了

    3.反射得到要调用的方法对象method

    Method [] methods = clazz.getMethods(); //获取当前类的所有public方法

    Method  method = clazz.getMethod("setName",String.class); 

    4.通过反射调用方法

    method.invoke(student,"张三");

    Method  getnamemethod= clazz.getMethod("getName"); 

    Object value = getnamemethod.invoke(student);

    然后就是名字就是value值了

    注意:

    1.如果一个解析xml文件的代码,并且会把解析出来的数据封装到一个对象中(student类)去,在xml文件标签名改了以后,也要把对象中(student类中的全局变量名也要改)全局变量名也要改,要不然反射时就找不到set或者get方法

    2.所以,当xml文件的标签名改了,正常调用解析封装到对象的代码就要改 对象和解析代码这几个地方,但反射的方法就只需要改对象中的全局变量就够了,反射方法代码不需要改

    test2.xml文件

    <?xml version="1.0" encoding="utf-8"?>
    <students>
        <!--这个是xml的注释格式-->
        <student>
            <StudentName>赵尼玛</StudentName>
            <StudentAge>28</StudentAge>
            <StudentGender></StudentGender>
        </student>
    </students>

    普通方法去解析这个xml文件中的学生信息,并封装到Student对象中去

    package com.my.packge6;
    
    import org.dom4j.Document;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;
    
    public class Parse1 {
        public static void main(String[] args) {
            Parse1 parse1 = new Parse1();
            List<Student> stulist = parse1.parse("src\main\test2.xml");
            for (Student student : stulist) {
                System.out.println(student);
            }
    
    
        }
    
        public  List<Student> parse(String filepath){
            //1.准备解析器对象
            SAXReader saxReader = new SAXReader();
            //2.获取Document对象
            try {
                Document document = saxReader.read(new File(filepath));
                //3.获取根节点
                Element root = document.getRootElement();
                //4.根据根节点遍历子节点,返回的是个列表
                List<Element> studentsElement= root.elements("student");
                //写个集合
                List<Student> list = new ArrayList<Student>();
                //5.通过循环取出每一个student元素进行处理
                for (Element    studentelement : studentsElement) {
    
                    String name = studentelement.elementText("StudentName");
                    String age = studentelement.elementText("StudentAge");
                    String gender = studentelement.elementText("StudentGender");
                    //拿到值封装到student对象中去
                    Student student = new Student(name,age,gender);
                    list.add(student);
                }
                return list;
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            return null;
        }
    }

    然后,这是通过反射去实现:

    package com.my.packge6;
    
    import org.dom4j.Document;
    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;
    
    public class Parse2 {
        public static void main(String[] args) {
            Parse2 parse1 = new Parse2();
            List<Student> stulist = parse1.parse("src\main\test2.xml");
            for (Student student : stulist) {
                System.out.println(student);
            }
    
    
        }
    
        public  List<Student> parse(String filepath){
            //1.准备解析器对象
            SAXReader saxReader = new SAXReader();
            //2.获取Document对象
            try {
                Document document = saxReader.read(new File(filepath));
                //3.获取根节点
                Element root = document.getRootElement();
                //4.根据根节点遍历子节点,返回的是个列表
                List<Element> studentsElement= root.elements("student");
                //写个集合
                List<Student> list = new ArrayList<Student>();
                //拿到学生类的字节码
                Class<Student> clazz =Student.class;
                //5.通过循环取出每一个student元素进行处理
                for (Element studentelement : studentsElement) {
                    //通过反射创建学生对象
                    Student student = clazz.newInstance();
                    //获取xml文件中子标签
                    List<Element> stuchildelements= studentelement.elements();
                    for (Element stuchildelement : stuchildelements) {
                       String eleName = stuchildelement.getName();
                       //获取子标签的值
                        String value = stuchildelement.getText();
                        //拼接方法名,得到要调用的方法
                        String methodname = "set"+eleName;
                        //调用setName方法来封装学生的姓名;getMethod方法中传入的是需要调用的方法名和该方法入参类型,没有入参类型,可以只填方法名
                        //反射得到要调用的方法对象
                        Method method = clazz.getMethod(methodname,String.class);
                        //通过方法对象反射调用setName方法
                        method.invoke(student, value);
                    }
                    list.add(student);
                }
                return list;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
  • 相关阅读:
    洛谷 P2327 [SCOI2005]扫雷 题解
    P1388 算式 题解
    P1281 书的复制 题解
    P2896 [USACO08FEB]一起吃饭Eating Together 题解
    P1140 相似基因 题解
    变量的解构赋值
    let 和 const 命令
    第一阶段站立会议8
    第一阶段站立会议7
    第一阶段站立会议6
  • 原文地址:https://www.cnblogs.com/zhaobobo001/p/14626544.html
Copyright © 2020-2023  润新知