反射入门

  • Java的反射机制实在运行状态中,对于一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的方法和属性,这种动态获取的获取信息以及动态调用对象的方法的功能称为java语言的反射
  • 想要解剖一个类,必须先要获取该类的字节码文件对象(类的信息都存储在这里面了呢),解剖使用的就是Class类对象
1.1 获取Class类型的对象
  // 方式一: 获取一个类字节码文件对象
        Person person = new Person("henson");
        Class aClass = person.getClass();
        // System.out.println(aClass);

        // 方式二:
        Class bClass = Person.class;

        // 方式三:
        // java.lang.ClassNotFoundException: Person
        Class cClass = Class.forName("com.cskaoyan.reflection.Person");      
1.2 通过反射获取类构造方法&&创建对象
   // 1. 获取类的字节码文件对象
        Class aClass = Class.forName("com.cskaoyan.reflection.Person");
        //获取public类型的
        Constructor[] constructors = aClass.getConstructors();
         //获取所有类型的
        Constructor[] declaredConstructors = aClass.getDeclaredConstructors();
        for (Constructor c : declaredConstructors) {
            System.out.println(c);
        }
        
        // 如何通过 Construtor 对象生成对象
        // T newInstance(Object... initargs)  Object[] 参数个数可以是任意个(包括0个)
        // Uses the constructor represented by this Constructor object to create and initialize
        // a new instance of the constructor's declaring class, with the specified initialization parameters.

        // 获取无参构造方法
        Constructor constructor = aClass.getConstructor();
        Object o = constructor.newInstance();
        System.out.println(o);

        // 获取两个参数的构造方法(public)
        // Constructor   getConstructor(Class... parameterTypes)

        //获取私有的方法;需要设置Access
        Constructor constructor1 = aClass.getDeclaredConstructor(String.class, int.class);
        // void setAccessible(boolean flag)
        //Set the accessible flag for this object to the indicated boolean value.
        constructor1.setAccessible(true);
        // 自动装箱 拆箱  把基本数据自动装箱成相应的引用数据类型 Integer
        Object allen = constructor1.newInstance("Allen", 18);
        System.out.println(allen);
    }

通过反射获取成员变量并使用

     // 1. 获取字节码文件对象
        Class aClass = Class.forName("com.cskaoyan.reflection.Person");
        // 2. 通过字节码文件对象获取属性(域)
        // 获取父类和自己公共的成员属性和静态属性(public)
           Field[] fields = aClass.getFields();
        // 获取自己定义的所有的成员属性和静态属性(包括private)
        Field[] declaredFields = aClass.getDeclaredFields();

        /*
            Person person = new Person();
            person.name = "Trista"; //public
            person.age = 18;       //private
         */

        Object o = aClass.newInstance();
        System.out.println(o);
        Field nameField = aClass.getField("name");
        // 第一参数:表示要对哪个对象进行赋值
        // 第二参数:该对象的该属性要新赋予的值
        nameField.set(o, "Trista");
        System.out.println(o);

        // NoSuchFieldException: age,private类型
        Field age = aClass.getDeclaredField("age");
        age.setAccessible(true);
        age.set(o, 18);
        System.out.println(o);
    }
获取成员方法
       //1 .获取字节码文件对象
        Class aClass = Class.forName("com.cskaoyan.reflection.Person");

        // 获取父类和子类中公共的成员方法和静态方法
         Method[] methods = aClass.getMethods();
        // 获取该类中声明的所有成员方法和静态方法
        Method[] declaredMethods = aClass.getDeclaredMethods();


      Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
        declaredConstructor.setAccessible(true);
        Object jenny = declaredConstructor.newInstance("Jenny", 18);
        // Object   invoke(Object obj, Object... args)
        // 获取某个方法
        Method getAge = aClass.getMethod("getAge");
        //相当于对象.方法,(有参数,再后面加上)
        Object invoke = getAge.invoke(jenny); // 自动拆箱
        System.out.println(invoke);

        //如果是private方法,设置Access
        Method show = aClass.getDeclaredMethod("show");
        show.setAccessible(true);
        Object result = show.invoke(jenny);
        System.out.println(result);

    }

注:
通过反射访问类

   private Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Person() {
    }

    Person(String name) {
        this.name = name;
    }

    private static void show() {
        System.out.println("show self");
    }

    public int getAge() {
        return age;
    }

你可能感兴趣的:(反射入门)