【commons-beanutils专题】002- ConstructorUtils 专题

【commons-beanutils专题】002- ConstructorUtils 专题

一、准备

0、ConstructorUtils 主要作用

主要用于通过反射技术操作对象的构造方法:执行构造方法、获得指定构造方法等;

普通和精确的区别:普通的会找到兼容类型的方法,精确的只会匹配到确切的参数类型的方法。

1、引入 commons-beanutils 依赖

<!--引入依赖commons-beanutils-->
<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.9.4</version>
</dependency>

2、pom.xml 文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zibo</groupId>
    <artifactId>zibo2022</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>zibo2022</name>
    <description>zibo2022</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--引入依赖commons-beanutils-->
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.9.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.7.1</version>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3、实体类

package com.zibo.zibo2022.constructor_utils.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author zibo
 * @date 2022/7/13 0013 18:29
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {

    /**
     * 名字
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 地址
     */
    private String address;

    /**
     * 单参数构造方法
     * @param name 名字
     */
    public Student(String name) {
        this.name = name;
    }

    /**
     * 多参数构造方法
     * @param name 名字
     * @param age 年龄
     */
    public Student(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 单参数构造方法
     * @param age 年龄
     */
    public Student(Integer age) {
        this.age = age;
    }

}

二、执行构造方法

1、执行构造方法 - 单个参数 - 自动获取类型

// 1、执行构造方法 - 单个参数 - 自动获取类型
try {
    Student student1 = ConstructorUtils.invokeConstructor(Student.class, "张三");
    System.out.println(student1.getName()); // 张三
} catch (NoSuchMethodException | IllegalAccessException |
         InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

2、执行构造方法 - 多个参数 - 自动获取类型

// 2、执行构造方法 - 多个参数 - 自动获取类型
try {
    // 参数列表
    Object[] args1 = new Object[] {"李四", 18};
    Student student2 = ConstructorUtils.invokeConstructor(Student.class, args1);
    System.out.println(student2.getName()); // 李四
    System.out.println(student2.getAge()); // 18
} catch (NoSuchMethodException | IllegalAccessException |
         InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

3、执行构造方法 - 多个参数 - 手动设置类型

// 3、执行构造方法 - 多个参数 - 手动设置类型
try {
    // 参数列表
    Object[] args1 = new Object[] {"王五", 20};
    // 参数类型列表
    Class<?>[] types = new Class[] {String.class, Integer.class};
    Student student3 = ConstructorUtils.invokeConstructor(Student.class, args1, types);
    System.out.println(student3.getName()); // 王五
    System.out.println(student3.getAge()); // 20
} catch (NoSuchMethodException | IllegalAccessException |
         InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

三、执行精确的构造方法

1、执行精确的构造方法 - 单个参数 - 自动获取类型

// 4、执行精确的构造方法 - 单个参数 - 自动获取类型
try {
    Student student4 = ConstructorUtils.invokeExactConstructor(Student.class, "张三");
    System.out.println(student4.getName()); // 张三
} catch (NoSuchMethodException | IllegalAccessException |
         InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

2、执行精确的构造方法 - 多个参数 - 自动获取类型

// 5、执行精确的构造方法 - 多个参数 - 自动获取类型
try {
    // 参数列表
    Object[] args1 = new Object[] {"李四", 18};
    Student student5 = ConstructorUtils.invokeExactConstructor(Student.class, args1);
    System.out.println(student5.getName()); // 李四
    System.out.println(student5.getAge()); // 18
} catch (NoSuchMethodException | IllegalAccessException |
         InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

3、执行精确的构造方法 - 多个参数 - 手动设置类型

// 6、执行精确的构造方法 - 多个参数 - 手动设置类型
try {
    // 参数列表
    Object[] args1 = new Object[] {"王五", 20};
    // 参数类型列表
    Class<?>[] types = new Class[] {String.class, Integer.class};
    Student student6 = ConstructorUtils.invokeExactConstructor(Student.class, args1, types);
    System.out.println(student6.getName()); // 王五
    System.out.println(student6.getAge()); // 20
} catch (NoSuchMethodException | IllegalAccessException |
         InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

四、指定类型,获取构造方法

1、指定一个类型,获取单参构造方法(测试1)

// 7、指定一个类型,获取单参构造方法(测试1)
try {
    Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, String.class);
    Student student7 = constructor.newInstance("马六");
    System.out.println(student7.getName()); // 马六
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

2、指定一个类型,获取单参构造方法(测试2)

// 8、指定一个类型,获取单参构造方法(测试2)
try {
    Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, Integer.class);
    Student student8 = constructor.newInstance(26);
    System.out.println(student8.getAge()); // 26
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

3、指定一个类型列表,获取多参构造方法

// 9、指定一个类型列表,获取多参构造方法
try {
    // 参数类型列表
    Class<?>[] types = new Class[] {String.class, Integer.class};
    Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, types);
    Student student9 = constructor.newInstance("马六", 26);
    System.out.println(student9.getName()); // 马六
    System.out.println(student9.getAge()); // 26
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

五、获取给定构造函数的可访问版本

// 10、获取给定构造函数的可访问版本
try {
    Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, Integer.class);
    Constructor<Student> constructor1 = ConstructorUtils.getAccessibleConstructor(constructor);
    Student student10 = constructor1.newInstance(26);
    System.out.println(student10.getAge()); // 26
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
    throw new RuntimeException(e);
}

六、完整代码

package com.zibo.zibo2022.constructor_utils.main;

import com.zibo.zibo2022.constructor_utils.entity.Student;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.beanutils.ConstructorUtils;

/**
 * @author zibo
 * @date 2022/7/13 0013 18:31
 */
public class Main {

    public static void main(String[] args) {
        // 1、执行构造方法 - 单个参数 - 自动获取类型
        try {
            Student student1 = ConstructorUtils.invokeConstructor(Student.class, "张三");
            System.out.println(student1.getName()); // 张三
        } catch (NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 2、执行构造方法 - 多个参数 - 自动获取类型
        try {
            // 参数列表
            Object[] args1 = new Object[] {"李四", 18};
            Student student2 = ConstructorUtils.invokeConstructor(Student.class, args1);
            System.out.println(student2.getName()); // 李四
            System.out.println(student2.getAge()); // 18
        } catch (NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 3、执行构造方法 - 多个参数 - 手动设置类型
        try {
            // 参数列表
            Object[] args1 = new Object[] {"王五", 20};
            // 参数类型列表
            Class<?>[] types = new Class[] {String.class, Integer.class};
            Student student3 = ConstructorUtils.invokeConstructor(Student.class, args1, types);
            System.out.println(student3.getName()); // 王五
            System.out.println(student3.getAge()); // 20
        } catch (NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 4、执行精确的构造方法 - 单个参数 - 自动获取类型
        try {
            Student student4 = ConstructorUtils.invokeExactConstructor(Student.class, "张三");
            System.out.println(student4.getName()); // 张三
        } catch (NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 5、执行精确的构造方法 - 多个参数 - 自动获取类型
        try {
            // 参数列表
            Object[] args1 = new Object[] {"李四", 18};
            Student student5 = ConstructorUtils.invokeExactConstructor(Student.class, args1);
            System.out.println(student5.getName()); // 李四
            System.out.println(student5.getAge()); // 18
        } catch (NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 6、执行精确的构造方法 - 多个参数 - 手动设置类型
        try {
            // 参数列表
            Object[] args1 = new Object[] {"王五", 20};
            // 参数类型列表
            Class<?>[] types = new Class[] {String.class, Integer.class};
            Student student6 = ConstructorUtils.invokeExactConstructor(Student.class, args1, types);
            System.out.println(student6.getName()); // 王五
            System.out.println(student6.getAge()); // 20
        } catch (NoSuchMethodException | IllegalAccessException |
                 InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 7、指定一个类型,获取单参构造方法(测试1)
        try {
            Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, String.class);
            Student student7 = constructor.newInstance("马六");
            System.out.println(student7.getName()); // 马六
        } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 8、指定一个类型,获取单参构造方法(测试2)
        try {
            Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, Integer.class);
            Student student8 = constructor.newInstance(26);
            System.out.println(student8.getAge()); // 26
        } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 9、指定一个类型列表,获取多参构造方法
        try {
            // 参数类型列表
            Class<?>[] types = new Class[] {String.class, Integer.class};
            Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, types);
            Student student9 = constructor.newInstance("马六", 26);
            System.out.println(student9.getName()); // 马六
            System.out.println(student9.getAge()); // 26
        } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

        // 10、获取给定构造函数的可访问版本
        try {
            Constructor<Student> constructor = ConstructorUtils.getAccessibleConstructor(Student.class, Integer.class);
            Constructor<Student> constructor1 = ConstructorUtils.getAccessibleConstructor(constructor);
            Student student10 = constructor1.newInstance(26);
            System.out.println(student10.getAge()); // 26
        } catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
            throw new RuntimeException(e);
        }

    }

}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值