Java反射入门

2023-12-26 17:55:29

基础

  1. 何为反射

通过反射,我们可以在运行时获取任意一个类的所有属性和方法,并且可以调用它们。

  1. 应用场景

JDK动态代理,注解的实现。

  1. 优缺点
  • 优点:代码更加灵活。

  • 缺点:安全问题,性能问题。

  1. Class类,保存程序运行时某个对象的所有信息。

  2. 获取Class类的方法

// 通过对象实例获取
obj.getClass();

// 通过全类名获取
Class.forName("cn.com.Example");

// 通过具体的类获取
Example.class;

// 通过类加载器传入全类名获取
ClassLoader.getSystemClassLoader().loadClass("cn.com.Example");

关于 Filed 类、Method 类、Constructor类。

  1. 是什么?
    java.lang.reflect 包下的 Filed 类、Method 类、Constructor 类分别用来描述类的字段、方法、构造器。
  2. 怎么获取?
  • getFileds()、getMethods()、getConstructors()方法分别返回这个类的公共字段、方法和构造器的数组(包括超类)。

    • public Field getField(String name) 获取指定字段
    • public Method getMethod(String name, Class<?>... parameterTypes) 获取指定方法
    • public Constructor<T> getConstructor(Class<?>... parameterTypes) 获取指定构造器

    补充 parameterTypes:因为方法或构造器可能同名,所有用 parameterTypes(传入参数类型的 Class 类) 区分不同的方法和构造器。

  • getDeclareFileds()、getDeclareMethods()、getDeclareConstructors() 方法返回所有字段、方法和构造器的数组(不包括超类)。对于单个字段、方法和构造器获取参考前面。

  1. 怎么使用?

    1. 对于 Filed 类:

      • public Object get(Object obj) 获取对象实例该字段的值。

      • public void set(Object obj, Object value) 设置对象实例该字段的值。value是设置的新值。

      1. 对于 Method 类:

        • public Object invoke(Object obj, Object... args) 调用对象实例的该方法。args是该方法需要的参数。
      2. 对于 Constructor 类:

        • public T newInstance(Object ... initargs) 根据构造器构造一个对象实例。initargs构造方法需要的参数

实战

public class Employee {
    private String name;
    private double salary;
    public Employee() {

    }
    public Employee(String name, double salary) {
        this.name = name;
        this.salary = salary;
    }
    public String getName() {
        return this.name;
    }
    public double raiseSalary(double raise) {
        return this.salary + raise;
    }

    public String toString() {
        return "name:" + this.name + ",salary:" + this.salary;
    }
}
public class Main {
    public static void main(String[] args) throws Exception {
        Employee jim = new Employee("Jim", 1000.0);

        Field nameFiled = Employee.class.getField("name");
        String o = (String) nameFiled.get(jim);
        System.out.println(o); // Jim
        nameFiled.set(jim, "jim");
        System.out.println(jim); // name:jim,salary:1000.0

        Method m1 = Employee.class.getMethod("getName");
        Method m2 = Employee.class.getMethod("raiseSalary", double.class);
        String name = (String) m1.invoke(jim);
        double salary = (double) m2.invoke(jim, 2000);
        System.out.println("name=" + name + ",salary=" + salary); // name=jim,salary=3000.0
        System.out.println(jim); // name:jim,salary:1000.0

        Constructor<Employee> constructor = Employee.class.getConstructor(String.class, double.class);
        Employee employee = constructor.newInstance("BBBB", 1000);
        System.out.println(employee); // name:BBBB,salary:1000.0
    }
}

文章来源:https://blog.csdn.net/m0_56199449/article/details/135225662
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。