学习反射3(反射获取构造方法)

目录

前言

如何获取 Constructor 对象

实例 

获取构造方法的权限修饰符

获取构造方法的方法名 

获取构造参数的参数个数

获取构造参数的参数类型

如何使用 Constructor 对象创建实例?

实例


前言

之前 学习了什么是反射 ? 如何使用反射 来创建实体类对象 ?本篇博客进一步学习如何使用反射,获得实体类中的构造方法。

温习以下反射的含义

反射:允许程序在运行时获取类的内部信息(如成员变量、成员方法、构造方法等),并能够动态操作这些信息。

了解 Java中常说的” 世间万物皆对象“ :把任何东西都看成一个一个 对象来理解 就比如之后学习 获取 类中的构造方法,成员变量、成员方法 就是把它们封装成一个个对象。在本篇博客中,就是把 构造方法 封装成 Constructor 类中的对象

如何获取 Constructor 对象

通过 Class 类的以下方法可以获取 Constructor 对象:

getConstructor(Class<?>... parameterTypes)获取指定的公共构造方法对象
getDeclaredConstructor(Class<?>... parameterTypes)获取指定的构造方法(包括私有构造方法)对象
getConstructors()获取所有的公共构造方法对象的数组
getDeclaredConstructors()获取所有的构造方法(包括私有构造方法)对象的数组

实例 

  • 获取类中的构造方法

打开 IDEA ,新建一个Student 类 有 name  和age 两个字段。我写了四个构造方法

第一个全参构造方法
public Student(String name, int age) {
    this.name = name;
    this.age = age;
}
只带一个参数的构造方法
public Student(String name) {
    this.name = name;
}
只带一个参数的构造方法
protected Student(int age) {
     this.age = age;
 }
无参构造方法
private Student() {
}

现在通过创建Test 测试类 演示 获得 类中的构造方法

步骤

  • 通过创建目标类的字节码文件对象
  • 根据实际情况获得指定构造方法对象还是对象数组

获取 类中全部的构造方法 对象数组

     try {
                 // 获取目标类的Class 类对象【字节码文件对象】
            Class<?> aClass = Class.forName("fs.exerise02.Student");
            // 类中全部的构造方法 对象数组
            Constructor<?>[] constructors = aClass.getConstructors();
            for (Constructor<?> constructor : constructors) {
                System.out.println(constructor);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

运行结果

发现,只能获取公共的构造方法 像 private 等其他的访问权限修饰符修饰的 构造方法是无法被创建的

获取全部的构造方法,只需要修改一处地方。使用 getDeclaredConstructors() 方法

     Constructor<?>[] constructors = aClass.getDeclaredConstructors();

运行结果

  • 获取指定构造方法对象

创建目标类的字节码文件对象

调用 getConstructor方法 或 getDeclaredConstructor方法 获得指定构造方法对象

 try {
            Class<?> aClass = Class.forName("fs.exerise02.Student");
            // 通过参数类型对应的字节码文件,获取指定构造方法
            Constructor constructor = aClass.getDeclaredConstructor();
            System.out.println(constructor);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

通过代码发现:

1 使用 getDeclaredConstructor() 方法 获得所有权限类型下的指定构造方法

2 该方法的构造方法 是空参

这里大概会猜到 运行之后的结果  是 获得一个无参的构造方法

如果我想要获得其他的构造方法,需要向 getDeclaredConstructor() 添加可变参数,并且参数类型是 目标类 类型的字节码文件对象 。

如 我想要获得 只带一个参数的 String  类型的构造方法

    Constructor constructor = aClass.getDeclaredConstructor(String.class);

运行结果

假设我将只带一个参数的 String  类型的构造方法 的权限修饰符改为private 并且我使用  getConstructor方法 看一看会发现什么?

之前说: getConstructor方法 只能获得公共的构造方法对象

private Student(String name) {
        this.name = name;
    }
  Constructor constructor = aClass.getConstructor(String.class);

运行结果

  • 会发现报错了,显示没有这样的 构造方法

发现:当使用 getConstructor方法 是存在一定的局限性的。只有当真正存在被public 修饰的 构造方法才可以。

如我想要获得 全参的构造方法

     Constructor constructor = aClass.getDeclaredConstructor(String.class, int.class);

运行结果

获取构造方法的权限修饰符

使用 getModifiers() 方法获得 权限修饰符,但我们跟我们想象的有点不同的是返回值 int 整型

  Constructor<?> con = aClass.getDeclaredConstructor(String.class, int.class);
            int modifiers = con.getModifiers();
            System.out.println(modifiers);

运行结果

那么它们之间的规律:

获取构造方法的方法名 

  System.out.println(con.getName());

运行结果

获取构造参数的参数个数

调用 getParameterCount() 方法获得参数个数

      Constructor<?> con = aClass.getDeclaredConstructor(String.class, int.class);
 int parameterCount = con.getParameterCount();
            System.out.println(parameterCount);

运行结果

获取构造参数的参数类型

调用 getParameterTypes() 获得参数类型, 返回值是一个存储参数类型 的数组

 Constructor<?> con = aClass.getDeclaredConstructor(String.class, int.class);
            Class<?>[] parameterTypes = con.getParameterTypes();
            for (Class<?> parameterType : parameterTypes) {
                System.out.println(parameterType);
            }

运行结果

如何使用 Constructor 对象创建实例?

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

T newInstance(Object...initargs)根据指定的构造方法创建对象
setAccessible(boolean flag)设置为true,表示取消访问检查

实例

延续之前的代码,通过反射 创建Student 类对象


        try {
            Class<?> aClass = Class.forName("fs.exerise02.Student");
            // 通过参数类型对应的字节码文件,获取指定构造方法
            Constructor<?> con = aClass.getDeclaredConstructor(String.class, int.class);
           Student student = (Student) con.newInstance("小明", 12);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值