• Java反射总结


    反射的具体原理以后说明,以下面代码实例来说明反射的应用。

    先写一个Person类

    package exercise01;
    
    public class Person {
        private String name;
        private int age;
        //无参构造方法
        public Person() {
            
        }
        //有参构造方法
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
        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 "Person [name=" + name + ", age=" + age + "]";
        }
    }

    获取Class对象的三种方法

    Class clazz1 = Person.class;
    Class clazz2 = new Person()。getClass();
    Class clazz3 = Class.forName("exercise01.Person"); //forName方法的参数是类的路径,即包名加类名

    Class对象中有三个数组,分别是

    private Constructor[] constructor;  //构造方法数组,存放目标类的构造器
    private Field[] field;  //属性数组,存放目标类属性
    private Method[] method;  //普通方法数组,存放目标类的普通方法

    得到三个数组的方法

        @Test
        public void getAll() throws Exception {
            Class clazz = Person.class;
            //得到构造器的数组
            Constructor[] constructor = clazz.getConstructors();
            //得到属性的数组
            Field[] field = clazz.getDeclaredFields();
            //得到普通方法的数组
            Method[] method = clazz.getDeclaredMethods();
        }

    注意:

    如果Class对象想设置目标类的私有属性或方法,要添加下面这个语句

    //获取Class对象
    Class clazz = Person.class;
    //获取Person类中的name属性
    Field field = clazz.getDeclaredField("name");
    //name的访问权限是private,通过下面语句获取权限,r然后Field对象就可以为name属性赋值了
    field.setAccessible(true);

    调用目标类的无参构造方法

    //获取无参的构造方法
        @Test
        public void getConstructor() throws Exception {
                    //获取Class类对象
            Class clazz = Person.class;
            //得到Person的实例
            Person p = (Person)cla.newInstance();
            p.setName("example");
            System.out.println(p.getName());
        }

    调用目标类的有参构造方法

    @Test
        public void getConstructors() throws Exception{
            Class clazz = Person.class;
            //传递的是有参构造方法里的参数类型,类型是class的形式
            /*
             * 这里int的class形式要用int.class,而不是Integer.class
             * 如果要用Integer.class,要把Person类的age改成Integer类型
             */
            Constructor cs = clazz.getConstructor(String.class, int.class);
            //通过有参数的构造方法设置值
            Person p1 = (Person)cs.newInstance("lila", 24);
            System.out.println(p1);
        }

    使用目标类的属性

    @Test
        public void getField() {
            try {
                Class clazz = Class.forName("exercise01.Person");
                //得到name属性
                //c2.getDeclaredFields(); //得到所有的属性
                Field field = clazz.getDeclaredField("name");
    //使用Person的无参构造方法实例化一个Person对象 Person person
    = (Person)clazz.newInstance(); //设置访问权限,使field可以操作私有属性 field.setAccessible(true); //设置person对象的name属性 field.set(person, "example"); System.out.println(f1.get(person)); }catch(Exception e) { e.printStackTrace(); } }

    使用目标类的普通方法

    @Test
        public void getMethod() throws Exception{
            Class clazz = Class.forName("exercise01.Person");
            //使用Person类的无参构造方法实例化一个Person对象
            Person person = (Person)clazz.newInstance();
            //获取一个Method对象,该方法包含Person类的setName方法
            /*
             * getDeclaredMethod方法第一个参数是目标类的目标方法名,第二个参数是目标方法的参数类型的class形式
             * 可以把目标方法的所有参数都写进去
             */
            Method method = clazz.getDeclaredMethod("setName", String.class);
            //设置权限
            method.setAccessible(true);
            method.invoke(person, "example");
            //访问静态方法
            //method.invoke(null, "example");
            System.out.println(person.getName());
        }

    这里有个值得注意的地方,如果要调用目标类的静态方法,此时invoke方法的书写方法有点不同。

    因为调用静态方法,不必实例化一个对象,可以通过类名直接调用,所以当使用静态方法时,invoke方法的第一个参数写成null,第二个参数写静态方法的参数的值,比如

    method.invoke(null, "example");
  • 相关阅读:
    spring cloud-zuul的Filter详解
    Hibernate day01
    JAVA中几种常用的RPC框架介绍
    乐观锁和悲观锁的区别(最全面的分析)
    Redis、Memcache和MongoDB的区别
    Hessian整合Spring
    Hessian的使用以及理解
    sso单点登录系统原理与实现
    zookeeper原理(转)
    Nginx的负载均衡的几种方式
  • 原文地址:https://www.cnblogs.com/songzj/p/7639759.html
Copyright © 2020-2023  润新知