js css htmlJava

Java反射

2022-11-19  本文已影响0人  h2coder

概述

在程序的运行过程中, 通过Class对象得到类中的信息(构造方法,成员方法,成员变量), 并操作他们。这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制。

Class对象

在Java中有一个类,类名就叫Class。Class类创建的对象我们成为Class对象

public class Class<T> {
    保存类中的信息(构造方法, 成员方法, 成员变量)
}

Class对象会保存类中的信息(构造方法, 成员方法, 成员变量等)
有了Class对象就能得到类中的所有信息。可以说得到Class对象反射就完成了一半。

class Class {
    //成员变量
    Field[] fs;
    //构造器
    Constructor[] cs;
    //成员方法
    Method[] ms;
}

获取Class对象的方式

三种获取Class对象的方式

Class<Person> clazz1 = Person.class;
Person p = new Person();
Class<? extends Person> clazz2 = p.getClass();
Class<?> clazz3 = Class.forName("com.zh.reflection.model.Person");

测试的实体类

class A {
    public int a;
}

public class Person extends A {
    public int aa;

    //成员变量
    private String name;
    private int age;

    //-------构造方法-------
    public Person() {
    }

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

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

    protected Person(int age) {
        this.age = age;
    }
    //-----------------------


    //-------get和set方法-------
    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;
    }


    //-------其他成员方法-------
    public void add(int a, int b) {
        int c = a + b;
        System.out.println("相加结果:" + c);
    }

    private int work(int hour) {
        System.out.println("一天工作" + hour + "小时");
        return hour * 100; //工资
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

准备工作

//获取Person类的字节码对象
Class<Person> clazz = Person.class;

反射构造方法(Constructor)

Class类中获取构造方法

//获取所有公开public修饰的构造方法
Constructor<?>[] constructors = clazz.getConstructors();
for (Constructor<?> constructor : constructors) {
    System.out.println(constructor);
}
//无参构造,getConstructor():公开修饰的
Constructor<Person> c2 = clazz.getConstructor();
System.out.println(c2);
//获取所有任意权限的构造方法
Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
    System.out.println(declaredConstructor);
}
//无参构造,getDeclaredConstructor():任意权限修饰的
Constructor<Person> c2 = clazz.getDeclaredConstructor();
System.out.println(c2);
//获取带参构造方法
Constructor<Person> c3 = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(c3);

反射构造方法创建对象

Constructor类中用于创建对象的方法

//反射获取无参构造方法
Constructor<Person> c1 = clazz.getConstructor();
//使用构造器创建对象
Person p1 = c1.newInstance();
System.out.println(p1);

//反射获取有参的构造方法,newInstance() 要传入实参
Constructor<Person> c2 = clazz.getConstructor(String.class, int.class);
Person p2 = c2.newInstance("张三", 18);
System.out.println(p2);

//反射获取私有的带参构造方法
Constructor<Person> c3 = clazz.getDeclaredConstructor(String.class);
//设置权限为允许范围,只针对对非空开
c3.setAccessible(true);
Person p3 = c3.newInstance("李四");
System.out.println(p3);

反射方法(Method)

Class类中获取成员方法

//获取所有公开public的方法(包括从父类继承而来的public方法)
Method[] ms1 = clazz.getMethods();
for (Method method : ms1) {
    System.out.println(method);
}
//获取公开的成员方法
Method ms3 = clazz.getMethod("add", int.class, int.class);
System.out.println(ms3);
//获取所有任意权限的方法(不包括父类,只包含本类的)
Method[] ms2 = clazz.getDeclaredMethods();
for (Method method : ms2) {
    System.out.println(method);
}
//获取单个任意权限的成员方法
Method ms4 = clazz.getDeclaredMethod("add", int.class, int.class);
System.out.println(ms4);

反射成员方法并调用

//反射创建对象实例
Constructor<Person> c1 = clazz.getConstructor();
Person person = c1.newInstance();
//反射获取公开public成员方法
Method ms1 = clazz.getMethod("add", int.class, int.class);
//调用成员方法,需传入实例对象和实参
ms1.invoke(person, 1, 2);
//反射获取私有成员方法
Method ms2 = clazz.getDeclaredMethod("work", int.class);
//设置为公开访问
ms2.setAccessible(true);
Object result = ms2.invoke(person, 8);
System.out.println(result);

反射成员变量(Field)

Class类中获取成员变量

Field f1 = clazz.getField("aa");
System.out.println(f1);
//获取公开的成员变量(包括从父类中继承的公开的变量)
Field[] fs1 = clazz.getFields();
for (Field field : fs1) {
    System.out.println(field);
}
Field f2 = clazz.getDeclaredField("name");
System.out.println(f2);
//获取任意权限的成员变量(只能是本类的,不包括父类的)
Field[] fs2 = clazz.getDeclaredFields();
for (Field declaredField : fs2) {
    System.out.println(declaredField);
}

反射成员变量修改值、获取值

//获取单个成员变量
Field f1 = clazz.getDeclaredField("age");
System.out.println(f1);
//设置为可访问
f1.setAccessible(true);
//变量赋值,set(调用者、实参值)
f1.set(person, 18);
//变量取值,get(调用者)
Object age = f1.get(person);
System.out.println(age);
上一篇 下一篇

猜你喜欢

热点阅读