美文网首页
Java-反射基本API

Java-反射基本API

作者: 王多鱼2 | 来源:发表于2019-09-30 14:30 被阅读0次

    1,什么是反射?

    反射就是在运行时才知道要操作的类是什么,并且可以在运行时获取类的完整构造,并调用对应的方法。

    2,类加载器相关

      //1. 获取一个系统的类加载器(可以获取,当前这个类PeflectTest就是它加载的)
            ClassLoader classLoader = ClassLoader.getSystemClassLoader();
            System.out.println(classLoader);
            //2. 获取系统类加载器的父类加载器(扩展类加载器,可以获取).
            classLoader = classLoader.getParent();
            System.out.println(classLoader);
            //3. 获取扩展类加载器的父类加载器(引导类加载器,不可获取).
            classLoader = classLoader.getParent();
            System.out.println(classLoader);
            //4. 测试当前类由哪个类加载器进行加载(系统类加载器):
            classLoader = Class.forName("cn.xxx.refle.more.ReflectionTest")
                    .getClassLoader();
            System.out.println(classLoader);
            //5. 测试 JDK 提供的 Object 类由哪个类加载器负责加载(引导类)
            classLoader = Class.forName("java.lang.Object")
                    .getClassLoader();
            System.out.println(classLoader);
    

    输出结果:

    sun.misc.Launcher$AppClassLoader@18b4aac2
    sun.misc.Launcher$ExtClassLoader@14ae5a5
    null
    sun.misc.Launcher$AppClassLoader@18b4aac2
    null
    

    3,构造器相关

    System.out.println("获取全部Constructor对象-----");

            String className = "cn.xxx.refle.more.Person";
            Class<Person> clazz = (Class<Person>) Class.forName(className);
            Constructor<Person>[] constructors
                    = (Constructor<Person>[]) clazz.getConstructors();
            for(Constructor<Person> constructor: constructors){
                System.out.println(constructor);
            }
    

    System.out.println("获取某一个Constructor 对象,需要参数列表----");

            Constructor<Person> constructor
                    = clazz.getConstructor(String.class, int.class);
            System.out.println(constructor);
    

    调用构造器的 newInstance() 方法创建对象

            //2. 调用构造器的 newInstance() 方法创建对象
            System.out.println("调用构造器的 newInstance() 方法创建对象-----");
            Person obj = constructor.newInstance("Mark", 18);
            System.out.println(obj.getName());
    

    3,方法相关

            Class clazz = Class.forName("cn.enjoyedu.refle.more.Person");
            System.out.println("获取clazz对应类中的所有方法," +
                    "不能获取private方法,且获取从父类继承来的所有方法");
            Method[] methods = clazz.getMethods();
            for(Method method:methods){
                System.out.print(" "+method.getName()+"()");
            }
            System.out.println("");
            System.out.println("---------------------------");
    
            System.out.println("获取所有方法,包括私有方法," +
                    "所有声明的方法,都可以获取到,且只获取当前类的方法");
            methods = clazz.getDeclaredMethods();
            for(Method method:methods){
                System.out.print(" "+method.getName()+"()");
            }
            System.out.println("");
            System.out.println("---------------------------");
    
            System.out.println("获取指定的方法," +
                    "需要参数名称和参数列表,无参则不需要写");
            //  方法public void setName(String name) {  }
            Method method = clazz.getDeclaredMethod("setName", String.class);
            System.out.println(method);
            System.out.println("---");
    
            //  方法public void setAge(int age) {  }
            /* 这样写是获取不到的,如果方法的参数类型是int型
            如果方法用于反射,那么要么int类型写成Integer: public void setAge(Integer age) {  }
            要么获取方法的参数写成int.class*/
            method = clazz.getDeclaredMethod("setAge", int.class);
            System.out.println(method);
            System.out.println("---------------------------");
    
    
            System.out.println("执行方法,第一个参数表示执行哪个对象的方法" +
                    ",剩下的参数是执行方法时需要传入的参数");
            Object obje = clazz.newInstance();
            method.invoke(obje,18);
    
            /*私有方法的执行,必须在调用invoke之前加上一句method.setAccessible(true);*/
            method = clazz.getDeclaredMethod("privateMethod");
            System.out.println(method);
            System.out.println("---------------------------");
    

    执行私有方法

            System.out.println("执行私有方法");
            method.setAccessible(true);
            method.invoke(obje);
    

    4,域相关

      String className = "cn.enjoyedu.refle.more.Person";
            Class clazz = Class.forName(className);
    
            System.out.println("获取公用和私有的所有字段,但不能获取父类字段");
            Field[] fields = clazz.getDeclaredFields();
            for(Field field: fields){
                System.out.print(" "+ field.getName());
            }
            System.out.println();
            System.out.println("---------------------------");
    
    
            System.out.println("获取指定字段");
            Field field = clazz.getDeclaredField("name");
            System.out.println(field.getName());
    
            Person person = new Person("ABC",12);
            System.out.println("获取指定字段的值");
            Object val = field.get(person);
            System.out.println(field.getName()+"="+val);
    
            System.out.println("设置指定对象指定字段的值");
            field.set(person,"DEF");
            System.out.println(field.getName()+"="+person.getName());
    
            System.out.println("字段是私有的,不管是读值还是写值," +
                    "都必须先调用setAccessible(true)方法");
            //     比如Person类中,字段name字段是非私有的,age是私有的
            field = clazz.getDeclaredField("age");
            field.setAccessible(true);
            System.out.println(field.get(person));
    

    5,Person 类

    public class Person {
        String name;
        private int age;
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
            System.out.println("this is setName()!");
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
            System.out.println("this is setAge()!");
        }
    
        //包含一个带参的构造器和一个不带参的构造器
        public Person(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
        public Person() {
            super();
        }
    
        //私有方法
        private void privateMethod(){
            System.out.println("this is private method!");
        }
    }
    

    相关文章

      网友评论

          本文标题:Java-反射基本API

          本文链接:https://www.haomeiwen.com/subject/hbswectx.html