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() { }
}
在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 USER_INFO_ENTITY_CLASS = UserInfoEntity.class;
@Test
public void testGetConstructors() {
// getConstructors 获取当前类中使用public定义的构造方法
Collection constructorNameList = Arrays.stream(USER_INFO_ENTITY_CLASS.getConstructors()).map(Constructor::toString).collect(Collectors.toList());
List 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);
}
@Test
public 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();
}
@Test
public void testGetDeclaredConstructors() {
// getDeclaredConstructors 获取当前类中定义的所有构造方法
Collection declaredConstructorNameList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructors()).map(Constructor::toString).collect(Collectors.toList());
List 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);
}
@Test
public 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方法获取当前类中定义的指定构造方法(使用构造方法的参数类型进行匹配)
在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 USER_INFO_ENTITY_CLASS = UserInfoEntity.class;
@Test
public 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);
}
@Test
public 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");
}
@Test
public 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)");
}
@Test
public 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();
}
@Test
public 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();
}
@Test
public 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);
}
@Test
public 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:使用所有参数的构造方法创建对象