• 反射笔记-----------------------------


    1.反射基本概念:

    01.定义:

    反射是指在程序运行期间,能够观察和修改类或者类的对象的属性和行为的特性!

    02.作用:

    001.在运行期间获取类的修饰符,包名,类名,实现的接口,继承的父类。

    002.在运行期间获取类的所有属性名,修饰符,属性类型。

    003.在运行期间获取所有方法,方法的返回值类型,方法名,方法参数数量,方法参数类型。

    004.在运行期间加载类的方法。

    03.java反射API常用的类

    001.java.lang.Class

    002.java.lang.reflect.Method

    003.java.lang.Constructor

    004.java.lang.Filed

    005.java.lang.Modifier

    2.例子

    01.使用java反射获取类的信息

    001.父类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 父类
     * 
     * @author Administrator
     * 
     */
    public class FatherTest {
        private String teststr = "测试用";
    
        public String getTeststr() {
            return teststr;
        }
    
        public void setTeststr(String teststr) {
            this.teststr = teststr;
        }
    
    }
    复制代码

    002.子类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 测试类 人类  继承了父类
     */
    import java.io.Serializable;
    
    public class Person extends FatherTest implements Serializable {
        private int id;
        private String name;
        private String address;
        private String message;
    
        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 String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public Person() {
            super();
    
        }
    
        public Person(int id, String name, String address, String message) {
            super();
            this.id = id;
            this.name = name;
            this.address = address;
            this.message = message;
        }
    
    }
    复制代码

    003.测试类代码:

    复制代码
    package cn.pb.test;
    
    
    /**
     * 测试类 通过反射获取类的信息
     * 
     * @author Administrator
     * 
     */
    public class GetClassInfo {
        public void test(String className) throws Exception {
            // 获取Person类对象 传递的className为类的全类名
            Class clazz = Class.forName(className);
    
            // 获取类在的包名 clazz.getSimpleName():获取类名
            Package pkg = clazz.getPackage();
            System.out.println(clazz.getSimpleName() + "定义在" + pkg.getName()
                    + "包中!");
            System.out.println("*********************");
    
            // 获取此对象所表示的实体(类,接口,基本类型或者void)的超类Class
            // 如果此对象是一个Object类,一个接口,一个基本类型或void,它的超类返回Null
            // 如果此对象是一个数组类,返回表示Object类的Class对象
            Class superClass = clazz.getSuperclass();
            System.out.println(clazz.getSimpleName() + "的超类是"
                    + superClass.getName());
            System.out.println("*********************");
    
            // 获取Person类所实现的接口
            // 如果Person类没有实现任何接口,返回一个长度为0的数组
            // 如果Person类是一个基本类型或者是void,那么也返回一个长度为0的数组
            Class[] interfaces = clazz.getInterfaces();
            System.out.println("所实现的接口有:");
            for (Class c : interfaces) {
                System.out.println(c.getName());
            }
            System.out.println("******************");
        }
    
        public static void main(String[] args) throws Exception {
            GetClassInfo getClassInfo = new GetClassInfo();
            getClassInfo.test("cn.pb.bean.Person");
        }
    
    }
    复制代码

    02.使用java反射获取类的构造函数的参数列表,并通过构造函数实例化类

    001.父类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 父类
     * 
     * @author Administrator
     * 
     */
    public class FatherTest {
        private String teststr = "测试用";
    
        public String getTeststr() {
            return teststr;
        }
    
        public void setTeststr(String teststr) {
            this.teststr = teststr;
        }
    
    }
    复制代码

    002.子类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 测试类 人类  继承了父类
     */
    import java.io.Serializable;
    
    public class Person extends FatherTest implements Serializable {
        private int id;
        private String name;
        private String address;
        private String message;
    
        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 String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public Person() {
            super();
            System.out.println("通过无参构造实例化Person对象");
        }
    
        public Person(int id, String name, String address, String message) {
            super();
            this.id = id;
            this.name = name;
            this.address = address;
            this.message = message;
            System.out.println("通过有参构造实例化Person对象");
        }
    
        @Override
        public String toString() {
            return "Person [id=" + id + ", name=" + name + ", address=" + address
                    + ", message=" + message + "]";
        }
    
    }
    复制代码

    003.测试代码

    复制代码
    package cn.pb.test;
    
    import java.lang.reflect.Constructor;
    
    /**
     * 使用java反射获取类的构造函数的参数列表,并通过构造函数实例化类
     * 
     * @author Administrator
     * 
     */
    public class GetClassConstructorInfo {
    
        /**
         * 通过反射实例化类的对象
         * 
         * @throws Exception
         */
        public void test1() throws Exception {
            // 参数calssName,为类的全类名
            Class clazz = Class.forName("cn.pb.bean.Person");
            // 通过clazz.newInstance()方法,获取类的实例
            Object obj = clazz.newInstance();
    
            System.out.println("通过反射实例化的对象:" + obj);
        }
    
        /**
         * 通过反射获取类的构造函数
         * 
         * @throws Exception
         */
        public void test2() throws Exception {
            // 参数calssName,为类的全类名
            Class clazz = Class.forName("cn.pb.bean.Person");
            // 获取类的构造函数,返回类的所有公共的构造函数
            Constructor[] constructors = clazz.getConstructors();
            System.out.println(clazz.getSimpleName() + "类的公共的构造函数以及构造函数的参数列表类型:");
            for (Constructor constructor : constructors) {
                System.out.println("构造函数的名称为:" + constructor.getName());
                // 获取构造函数的所有参数
                Class[] params = constructor.getParameterTypes();
                if (params.length == 0) {
                    System.out.println("此构造函数没有参数!");
                } else {
                    System.out.println("该构造函数的参数列表为:【");
                    for (int i = 0; i < params.length; i++) {
                        if (i != 0) {
                            System.out.println(",");
                        }
                        System.out.println(params[i].getName());
                    }
                    System.out.println("】");
                }
            }
    
            // 获取无参构造,如果参数为空,则获取无参构造
            Constructor constructor = clazz.getConstructor();
            // 通过无参构造方法获取类的实例
            Object obj = constructor.newInstance();
            System.out.println("通过无参构造实例化的对象为:" + obj);
    
            /**
             * 获取有参构造 这个方法只能获得公共的有参构造 想要获取私有的构造方法 可以使用
             * clazz.getDeclaredConstructor(int.class, String.class, String.class,
             * String.class);方法
             */
    
            Constructor constructor2 = clazz.getConstructor(int.class,
                    String.class, String.class, String.class);
    
            Object obj2 = constructor2.newInstance(12, "xiix", "hah", "wawa");
    
            System.out.println("通过有参构造实例化的 对象为:" + obj2);
        }
    
        public static void main(String[] args) throws Exception {
            GetClassConstructorInfo test = new GetClassConstructorInfo();
            // test.test1();
            test.test2();
        }
    }
    复制代码

     03.使用java反射获取类的所有方法的信息,并调用类的setter方法进行属性的赋值

    001.父类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 父类
     * 
     * @author Administrator
     * 
     */
    public class FatherTest {
        private String teststr = "测试用";
    
        public String getTeststr() {
            return teststr;
        }
    
        public void setTeststr(String teststr) {
            this.teststr = teststr;
        }
    
    }
    复制代码

    002.子类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 测试类 人类  继承了父类
     */
    import java.io.Serializable;
    
    public class Person extends FatherTest implements Serializable {
        private int id;
        private String name;
        private String address;
        private String message;
    
        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 String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public Person() {
            super();
            System.out.println("通过无参构造实例化Person对象");
        }
    
        public Person(int id, String name, String address, String message) {
            super();
            this.id = id;
            this.name = name;
            this.address = address;
            this.message = message;
            System.out.println("通过有参构造实例化Person对象");
        }
    
        @Override
        public String toString() {
            return "Person [id=" + id + ", name=" + name + ", address=" + address
                    + ", message=" + message + "]";
        }
    
    }
    复制代码

    003.测试代码

    复制代码
    package cn.pb.test;
    
    /**
     * 使用java反射获取类的所有方法的信息,并调用类的setter方法进行属性的赋值
     */
    import java.lang.reflect.Method;
    
    public class GetClassMethodsInfo {
    
        /**
         * 调用类的setter方法进行属性的赋值
         * 
         * @param className
         *            类的全类名
         * @param propName
         *            属性名
         * @param propType
         *            属性类型
         * @param propValue
         *            属性值
         * @throws Exception
         */
        public void invokeSetter(String className, String propName,
                String propType, Object propValue) throws Exception {
    
            // 通过反射获取类的实例
            Class clazz = Class.forName(className);
            Object obj = clazz.newInstance();
            // 将传过来的属性名 转换成set方法
            String methodName = "set" + propName.substring(0, 1).toUpperCase()
                    + propName.substring(1);
            // 根据set方法名和参数列表获取set方法
            Method method = clazz.getDeclaredMethod(methodName,
                    Class.forName(propType));
    
            // 如果需要可以设置setAccessible方法,设置为可以访问
            // method.setAccessible(true);
            // 调用方法并传参 参数为:方法所属的对象和方法的参数
            method.invoke(obj, propValue);//
    
            System.out.println("通过set方法给类的属性赋值:" + obj);
        }
    
        /**
         * 使用java反射获取类的所有方法的信息
         */
        public void showMethods() throws Exception {
            Method[] methods;
    
            // 获取Person类中的所有的方法,不包括继承的类的方法
            // 如果该类或接口没有生命任何方法,或者此Class 对象表示一个基本数据类型,一个数组类或void
            // 那么返回一个长度为0的数组
            methods = Class.forName("cn.pb.bean.Person").getDeclaredMethods();
    
            System.out.println("******展示方法信息********");
            for (Method method : methods) {
                System.out.println("方法名:" + method.getName());
                System.out.println("方法返回值类型:" + method.getReturnType().getName());
    
                // 获取方法的参数列表
                Class[] params = method.getParameterTypes();
                if (params.length == 0) {
                    System.out.println("该方法没有参数!");
                } else {
                    System.out.println("该方法的参数列表为:【");
                    for (int i = 0; i < params.length; i++) {
                        if (i != 0) {
                            System.out.println(",");
                        }
                        System.out.println(params[i].getName());
                    }
                    System.out.println("】");
                }
    
                // 获取方法所属的类或接口的class对象
                Class declaringClass = method.getDeclaringClass();
                System.out.println("方法声明在:" + declaringClass.getName() + "中!");
    
                // 获取方法抛出的异常的类型,即throws子句中声明的异常
                Class[] exceptions = method.getExceptionTypes();
                if (exceptions.length > 0) {
                    System.out.println("该方法抛出的异常有:【");
                    for (int i = 0; i < exceptions.length; i++) {
                        if (i != 0) {
                            System.out.println(",");
                        }
                        System.out.println(exceptions[i].getName());
                    }
                    System.out.println("】");
                }
    
                System.out.println("***********************");
    
            }
        }
    
        public static void main(String[] args) throws Exception {
            GetClassMethodsInfo test = new GetClassMethodsInfo();
            // test.invokeSetter("cn.pb.bean.Person", "name", "java.lang.String",
            // "zhangsan");
            test.showMethods();
        }
    }
    复制代码

     04.使用java反射获取类的所有属性的名称和类型,并为其中一个属性赋值

    001.父类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 父类
     * 
     * @author Administrator
     * 
     */
    public class FatherTest {
        private String teststr = "测试用";
    
        public String getTeststr() {
            return teststr;
        }
    
        public void setTeststr(String teststr) {
            this.teststr = teststr;
        }
    
    }
    复制代码

    002.子类代码

    复制代码
    package cn.pb.bean;
    
    /**
     * 测试类 人类  继承了父类
     */
    import java.io.Serializable;
    
    public class Person extends FatherTest implements Serializable {
        private int id;
        private String name;
        private String address;
        private String message;
    
        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 String getAddress() {
            return address;
        }
    
        public void setAddress(String address) {
            this.address = address;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    
        public Person() {
            super();
            System.out.println("通过无参构造实例化Person对象");
        }
    
        public Person(int id, String name, String address, String message) {
            super();
            this.id = id;
            this.name = name;
            this.address = address;
            this.message = message;
            System.out.println("通过有参构造实例化Person对象");
        }
    
        @Override
        public String toString() {
            return "Person [id=" + id + ", name=" + name + ", address=" + address
                    + ", message=" + message + "]";
        }
    
    }
    复制代码

    003.测试代码

    复制代码
    package cn.pb.test;
    
    import java.lang.reflect.Field;
    
    /**
     * 使用java反射获取类的所有属性的名称和类型,并为其中一个属性赋值
     * 
     * @author Administrator
     * 
     */
    public class GetClassFieldsInfo {
        /**
         * 使用java反射获取类的所有属性的名称和类型
         * 
         * @throws Exception
         */
        public void showFields() throws Exception {
            Field[] fields;
    
            // 获取Person类中的所有字段,但不包括继承的字段
            // 如果该类或接口不声明任何字段,或者此Class 对象表示一个基本数据类型,一个数组类或void
            // 那么返回一个长度为0的数组
            fields = Class.forName("cn.pb.bean.Person").getDeclaredFields();
    
            // 遍历
            System.out.println("**********字段展示***********");
            for (Field field : fields) {
                System.out.println("字段名:" + field.getName());
                System.out.println("字段类型:" + field.getType().getName());
                System.out.println("********************");
            }
        }
    
        /**
         * 通过使用反射操作person类的字段 使用java反射获取类的对象的实例,并为其中一个属性赋值
         */
        public void accessField() throws Exception {
            // 通过反射加载一个Person实例
            Class clazz = Class.forName("cn.pb.bean.Person");
            Object obj = clazz.newInstance();
    
            // 通过getDeclaredField("address")方法 获取类的指定字段
            Field address = clazz.getDeclaredField("address");
            // address字段为private,这里已经超出其访问范围,不能直接访问
            // 通过setAccessable方法,设定为可以访问
            address.setAccessible(true);
    
            System.out.println("赋值前的address:" + address.get(obj));
            // 为address属性赋值
            address.set(obj, "北大青鸟");
            System.out.println("赋值之后的address:" + address.get(obj));
        }
    
        public static void main(String[] args) throws Exception {
            GetClassFieldsInfo test = new GetClassFieldsInfo();
            test.showFields();
            test.accessField();
        }
    
    }
  • 相关阅读:
    scp 跨服务器传数据
    Mongo启动失败解决方案
    centos7 NET模式配置虚拟机
    centos7虚拟机配置桥接模式
    Linux centos7 查看cpu 磁盘 内存使用情况
    centos7修改时间和时区
    fiddler培训
    docker学习笔记
    docker-ce安装官翻
    Nginx+Tomcat简单负载均衡
  • 原文地址:https://www.cnblogs.com/laosunlaiye/p/7679337.html
Copyright © 2020-2023  润新知