liujijiang

java - 反射

2020.05.10

反射

已知的对象可以直接创建对象

Student类:

    class Student{
        private String name;

        public int age;

        public Student(String name, int age){
            this.name = name;

            this.age = age;
        }

        public Student(){

        }

        public String getName(){
            return name;
        }

        public void setName(String name){
            this.name = name;
        }

        private void ageAdd(){
            this.age++;
        }

        @Override
        public String toString() {
            return "name: " + this.name + " age: " + this.age;
        }
    }

// 直接创建对象
        Student student1 = new Student("redarm",10);
        System.out.println(student1.toString());

如果是在运行时才知道对象,那么可以利用反射创建对象
java编译后每个对象都会生成一个字节码文件,反射可以利用字节码文件在运行时创建对象,可以拿到任意一个类的属性,方法

利用反射创建对象,获取类的信息

package com.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @Author redarm
 * @Date 2020/5/10 1:20 下午
 **/
public class Test {

    public static void main(String[] args) throws Exception{
        
        // 反射

        // 得到对象字节码的两种方式
        Class student2 = Student.class;
        //Class two = Class.forName("Student");

        // 得到对象的构造器然后调用构造器创建一个新的实例
        Constructor constructor = student2.getConstructor(String.class, int.class);
        Object o = constructor.newInstance("name",1);

        // 直接创建对象
        //Object o = student2.newInstance();

        System.out.println(o.toString());

        // 拿到对象的setname方法, 调用方法改变对象 o 的名字
        Method init = student2.getMethod("setName", String.class);
        init.invoke(o,"changedName");

        System.out.println(o.toString());

        // 拿到对象的公有属性
        Field[] fields = student2.getFields();

        for (Field field : fields){
            System.out.println(field.toString());
        }

        // 对象的方法
        Method[] methods = student2.getMethods();

        for (Method method : methods){
            System.out.println(method.toString());
        }

        // 对象的构造器
        Constructor[] constructors = student2.getConstructors();

        for (Constructor constructor1: constructors){
            System.out.println(constructor1.toString());
        }
    }
}


输出所有成员变量的权限,属性,名字,包括private:

Class student = Class.forName("com.reflection.Student");

            Field[] fields = student.getDeclaredFields();

            for (Field field : fields){
                System.out.println(field.getModifiers());
                System.out.println(field.getName());
                System.out.println(field.getType());
            }

输出所有方法的信息,包括private:

Class student = Class.forName("com.reflection.Student");

            Method[] methods = student.getDeclaredMethods();

            for (Method method : methods){
                System.out.println(method.getModifiers());
                System.out.println(method.getName());
                System.out.println(method.getTypeParameters());
            }

利用反射访问私有方法

public static void main(String[] args) throws Exception{

            Class studentClass = Class.forName("com.reflection.Student");

            Object student = studentClass.newInstance();

            Method method = studentClass.getDeclaredMethod("ageAdd");

            method.setAccessible(true);

            System.out.println(student.toString());

            method.invoke(student);

            System.out.println(student.toString());
        }

invoke方法参数:调用方法的对象,方法参数

利用反射访问并直接修改私有属性

public static void main(String[] args) throws Exception{

            Class studentClass = Class.forName("com.reflection.Student");

            Object student = studentClass.newInstance();

            System.out.println(student.toString());

            Field field = studentClass.getDeclaredField("name");

            field.setAccessible(true);

            field.set(student,"newName");

            System.out.println(student.toString());
        }

拿到属性,设置允许访问,修改属性