Constructor类中包含了构造方法定义的详细信息,可以使用Constructor类中提供的方法来获取构造方法的信息,下面我们先获取Constructor对象,再介绍如何使用Constructor类中的newInstance方法创建对象。
一、准备工作
在src/test/java目录的cn.horse.reflect.entity包下新建BaseEntity类、UserInfoEntity类
BaseEntity类:
package cn.horse.reflect.entity;public abstract class BaseEntity {public Long id;public BaseEntity() { }public BaseEntity(Long id) {this.id = id;}public void setId(Long id) {this.id = id;}public Long getId() {return id;}
}
UserInfoEntity类:
package cn.horse.reflect.entity;@SuppressWarnings({})
public class UserInfoEntity extends BaseEntity {public String name;private Integer age;private UserInfoEntity() {}public UserInfoEntity(Long id) {super(id);}public UserInfoEntity(Long id, String name, Integer age) {super(id);this.name = name;this.age = age;}public void setAge(Integer age) {this.age = age;}public Integer getAge() {return age;}private String getName() {return name;}private void check() { }
}
二、获取Constructor对象
在src/test/java目录的cn.horse.reflect包下新建GetConstructorInstanceTests测试类
GetConstructorInstanceTests类:
package cn.horse.reflect;import cn.horse.reflect.entity.UserInfoEntity;
import org.junit.jupiter.api.Test;import java.lang.reflect.Constructor;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;public class GetConstructorInstanceTests {static final Class<UserInfoEntity> USER_INFO_ENTITY_CLASS = UserInfoEntity.class;@Testpublic void testGetConstructors() {// getConstructors 获取当前类中使用public定义的构造方法Collection<String> constructorNameList = Arrays.stream(USER_INFO_ENTITY_CLASS.getConstructors()).map(Constructor::toString).collect(Collectors.toList());List<String> expectedConstructorNameList = Arrays.asList("public cn.horse.reflect.entity.UserInfoEntity(java.lang.Long)", "public cn.horse.reflect.entity.UserInfoEntity(java.lang.Long,java.lang.String,java.lang.Integer)");assertThat(constructorNameList.size()).isEqualTo(expectedConstructorNameList.size());assertThat(constructorNameList).containsAll(expectedConstructorNameList);}@Testpublic void testGetConstructor() throws NoSuchMethodException {assertThatExceptionOfType(NoSuchMethodException.class).isThrownBy(() -> USER_INFO_ENTITY_CLASS.getConstructor());assertThat(USER_INFO_ENTITY_CLASS.getConstructor(Long.class)).isNotNull();assertThat(USER_INFO_ENTITY_CLASS.getConstructor(Long.class, String.class, Integer.class)).isNotNull();}@Testpublic void testGetDeclaredConstructors() {// getDeclaredConstructors 获取当前类中定义的所有构造方法Collection<String> declaredConstructorNameList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructors()).map(Constructor::toString).collect(Collectors.toList());List<String> expectedDeclaredConstructorNameList = Arrays.asList("private cn.horse.reflect.entity.UserInfoEntity()", "public cn.horse.reflect.entity.UserInfoEntity(java.lang.Long)", "public cn.horse.reflect.entity.UserInfoEntity(java.lang.Long,java.lang.String,java.lang.Integer)");assertThat(declaredConstructorNameList.size()).isEqualTo(expectedDeclaredConstructorNameList.size());assertThat(declaredConstructorNameList).containsAll(expectedDeclaredConstructorNameList);}@Testpublic void testGetDeclaredConstructor() throws NoSuchMethodException {assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor()).isNotNull();assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class)).isNotNull();assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class)).isNotNull();}
}
单元测试方法介绍:
testGetConstructors:使用getConstructors方法获取当前类中使用public定义的构造方法
testGetConstructor:使用getConstructor方法获取当前类中使用public定义的指定构造方法(使用构造方法的参数类型进行匹配)
testGetDeclaredConstructors:使用getDeclaredConstructors方法获取当前类中定义的所有构造方法
testGetDeclaredConstructor:使用getDeclaredConstructor方法获取当前类中定义的指定构造方法(使用构造方法的参数类型进行匹配)
三、Constructor类中方法的使用
在src/test/java目录的cn.horse.reflect包下新建ConstructorInstanceMethodTests测试类
ConstructorInstanceMethodTests类:
package cn.horse.reflect;import cn.horse.reflect.entity.UserInfoEntity;
import org.junit.jupiter.api.Test;import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Modifier;import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;public class ConstructorInstanceMethodTests {static final Class<UserInfoEntity> USER_INFO_ENTITY_CLASS = UserInfoEntity.class;@Testpublic void testGetDeclaringClass() throws NoSuchMethodException {assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getDeclaringClass()).isEqualTo(UserInfoEntity.class);assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class).getDeclaringClass()).isEqualTo(UserInfoEntity.class);assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class).getDeclaringClass()).isEqualTo(UserInfoEntity.class);}@Testpublic void testGetName() throws NoSuchMethodException {assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getName()).isEqualTo("cn.horse.reflect.entity.UserInfoEntity");assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class).getName()).isEqualTo("cn.horse.reflect.entity.UserInfoEntity");assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class).getName()).isEqualTo("cn.horse.reflect.entity.UserInfoEntity");}@Testpublic void testToString() throws NoSuchMethodException {assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().toString()).isEqualTo("private cn.horse.reflect.entity.UserInfoEntity()");assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class).toString()).isEqualTo("public cn.horse.reflect.entity.UserInfoEntity(java.lang.Long)");assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class).toString()).isEqualTo("public cn.horse.reflect.entity.UserInfoEntity(java.lang.Long,java.lang.String,java.lang.Integer)");}@Testpublic void testGetModifiers() throws NoSuchMethodException {assertThat(Modifier.isPrivate(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getModifiers())).isTrue();assertThat(Modifier.isPublic(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class).getModifiers())).isTrue();assertThat(Modifier.isPublic(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class).getModifiers())).isTrue();}@Testpublic void testNoArgsConstructorCreateInstance() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {// 获取private定义的无参数的构造方法创建对象Constructor<?> noArgsConstructor = USER_INFO_ENTITY_CLASS.getDeclaredConstructor();assertThatExceptionOfType(IllegalAccessException.class).isThrownBy(() -> noArgsConstructor.newInstance());noArgsConstructor.setAccessible(true);Object noArgsConstructorInstance = noArgsConstructor.newInstance();assertThat(noArgsConstructorInstance).isInstanceOf(USER_INFO_ENTITY_CLASS);assertThat(((UserInfoEntity) noArgsConstructorInstance).getId()).isNull();}@Testpublic void testIdArgsConstructorCreateInstance() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {// 获取public定义的参数只有id的构造方法创建对象Constructor<?> idArgsConstructor = USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class);Object idArgsConstructorInstance = idArgsConstructor.newInstance(200L);assertThat(idArgsConstructorInstance).isInstanceOf(USER_INFO_ENTITY_CLASS);assertThat(((UserInfoEntity) idArgsConstructorInstance).getId()).isEqualTo(200L);}@Testpublic void testAllArgsConstructorCreateInstance() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {// 获取public定义的参数包含id,name,age的构造方法创建对象Constructor<?> allArgsConstructor = USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class);Object allArgsConstructorInstance = allArgsConstructor.newInstance(200L, "张三", 10);assertThat(allArgsConstructorInstance).isInstanceOf(USER_INFO_ENTITY_CLASS);assertThat(((UserInfoEntity) allArgsConstructorInstance).getId()).isEqualTo(200L);assertThat(((UserInfoEntity) allArgsConstructorInstance).name).isEqualTo("张三");assertThat(((UserInfoEntity) allArgsConstructorInstance).getAge()).isEqualTo(10);}
}
单元测试方法介绍:
testGetDeclaringClass:获取声明类的Class对象,getDeclaringClass方法获取到的Class对象是构造方法所在类的Class对象
testGetName:获取名称,getName方法获取到的名称是构造方法所在类的名称
testToString:转换成字符串,toString方法用于将构造方法对象转换成字符串
testGetModifiers:获取修饰符,使用getModifiers获取修饰符,并使用Modifier类提供的静态方法依次判断了是否使用了public、private、protected等修饰符
testNoArgsConstructorCreateInstance:使用无参数的构造方法创建对象,方法中首先获取了无参数的构造方法,直接使用newInstance创建对象会抛出IllegalAccessException异常,原因是构造方法使用了private修饰,这里使用setAccessible设置访问了访问全限后在使用newInstance创建对象就可以了
testIdArgsConstructorCreateInstance:使用id参数的构造方法创建对象
testAllArgsConstructorCreateInstance:使用所有参数的构造方法创建对象