Constructor类中包含了构造方法定义的详细信息,可以使用Constructor类中提供的方法来获取构造方法的信息,下面我们先获取Constructor对象,再介绍如何使用Constructor类中的newInstance方法创建对象。
在src/test/java目录的cn.horse.reflect.entity包下新建BaseEntity类、UserInfoEntity类;新建EntityAnnotation、InheritedEntityAnnotation、UserInfoEntityAnnotation注解
BaseEntity类:
- package cn.horse.reflect.entity;
-
- @EntityAnnotation
- @InheritedEntityAnnotation
- public abstract class BaseEntity {
- @EntityAnnotation
- @InheritedEntityAnnotation
- public Long id;
-
- @InheritedEntityAnnotation
- public BaseEntity() { }
-
- @EntityAnnotation
- @InheritedEntityAnnotation
- public BaseEntity(Long id) {
- this.id = id;
- }
-
- @EntityAnnotation
- @InheritedEntityAnnotation
- public void setId(Long id) {
- this.id = id;
- }
-
- public Long getId() {
- return id;
- }
- }
UserInfoEntity类:
- package cn.horse.reflect.entity;
-
- @UserInfoEntityAnnotation
- public class UserInfoEntity extends BaseEntity {
-
- @UserInfoEntityAnnotation
- public String name;
- @UserInfoEntityAnnotation
- private Integer age;
-
- @UserInfoEntityAnnotation
- private UserInfoEntity() {
- }
-
- @UserInfoEntityAnnotation
- public UserInfoEntity(Long id) {
- super(id);
- }
-
- @UserInfoEntityAnnotation
- 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() { }
-
- @UserInfoEntityAnnotation
- @Override
- public void setId(Long id) {
- super.setId(id);
- }
- }
EntityAnnotation注解:
- package cn.horse.reflect.entity;
-
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- import static java.lang.annotation.ElementType.*;
-
- @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
- @Retention(RetentionPolicy.RUNTIME)
- public @interface EntityAnnotation {
- }
InheritedEntityAnnotation注解:
- package cn.horse.reflect.entity;
-
- import java.lang.annotation.Inherited;
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- import static java.lang.annotation.ElementType.*;
- import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-
- @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
- @Retention(RetentionPolicy.RUNTIME)
- @Inherited
- public @interface InheritedEntityAnnotation {
- }
UserInfoEntityAnnotation注解:
- package cn.horse.reflect.entity;
-
- import java.lang.annotation.Retention;
- import java.lang.annotation.RetentionPolicy;
- import java.lang.annotation.Target;
-
- import static java.lang.annotation.ElementType.*;
- import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-
- @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
- @Retention(RetentionPolicy.RUNTIME)
- public @interface UserInfoEntityAnnotation {
- }
在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.EntityAnnotation;
- import cn.horse.reflect.entity.InheritedEntityAnnotation;
- import cn.horse.reflect.entity.UserInfoEntity;
- import cn.horse.reflect.entity.UserInfoEntityAnnotation;
- import org.junit.jupiter.api.Test;
-
- import java.lang.annotation.Annotation;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Modifier;
- 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 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);
- }
-
- @Test
- public void testNoArgsConstructorGetAnnotations() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getAnnotations()).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testIdArgsConstructorGetAnnotations() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class).getAnnotations()).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testAllArgsConstructorGetAnnotations() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class).getAnnotations()).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testConstructorGetAnnotationsByType() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getAnnotationsByType(UserInfoEntityAnnotation.class)).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testConstructorGetAnnotation() throws NoSuchMethodException {
- assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getAnnotation(EntityAnnotation.class)).isNull();
- assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getAnnotation(InheritedEntityAnnotation.class)).isNull();
- assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
- }
-
-
- @Test
- public void testNoArgsConstructorGetDeclaredAnnotations() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getDeclaredAnnotations()).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testIdArgsConstructorGetDeclaredAnnotations() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class).getDeclaredAnnotations()).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testAllArgsConstructorGetDeclaredAnnotations() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class).getDeclaredAnnotations()).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testConstructorGetDeclaredAnnotationsByType() throws NoSuchMethodException {
- Collection
extends Annotation>> annotationList = Arrays.stream(USER_INFO_ENTITY_CLASS.getDeclaredConstructor(Long.class, String.class, Integer.class).getDeclaredAnnotationsByType(UserInfoEntityAnnotation.class)).map(Annotation::annotationType).collect(Collectors.toList()); - List
extends Annotation>> expectedAnnotationList = Arrays.asList(UserInfoEntityAnnotation.class); - assertThat(annotationList.size()).isEqualTo(expectedAnnotationList.size());
- assertThat(annotationList).containsAll(expectedAnnotationList);
- }
-
- @Test
- public void testConstructorGetDeclaredAnnotation() throws NoSuchMethodException {
- assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getDeclaredAnnotation(EntityAnnotation.class)).isNull();
- assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getDeclaredAnnotation(InheritedEntityAnnotation.class)).isNull();
- assertThat(USER_INFO_ENTITY_CLASS.getDeclaredConstructor().getDeclaredAnnotation(UserInfoEntityAnnotation.class)).isNotNull();
- }
- }
单元测试方法介绍:
testGetDeclaringClass:获取声明类的Class对象,getDeclaringClass方法获取到的Class对象是构造方法所在类的Class对象
testGetName:获取名称,getName方法获取到的名称是构造方法所在类的名称
testToString:转换成字符串,toString方法用于将构造方法对象转换成字符串
testGetModifiers:获取修饰符,使用getModifiers获取修饰符,并使用Modifier类提供的静态方法依次判断了是否使用了public、private、protected等修饰符
testNoArgsConstructorCreateInstance:使用无参数的构造方法创建对象,方法中首先获取了无参数的构造方法,直接使用newInstance创建对象会抛出IllegalAccessException异常,原因是构造方法使用了private修饰,这里使用setAccessible设置访问了访问全限后在使用newInstance创建对象就可以了
testIdArgsConstructorCreateInstance:使用id参数的构造方法创建对象
testAllArgsConstructorCreateInstance:使用所有参数的构造方法创建对象
testGetAnnotations:使用getAnnotations获取当前类的注解
testGetAnnotationsByType:使用getAnnotationsByType从当前类的注解中获取指定类型的注解
testGetAnnotation:使用getAnnotation从当前类的注解中获取指定类型的注解
testGetDeclaredAnnotations:使用getDeclaredAnnotations获取当前类的注解
testGetDeclaredAnnotationsByType:使用getDeclaredAnnotationsByType从当前类的注解中获取指定类型的注解
testGetDeclaredAnnotation:使用getDeclaredAnnotation从当前类的注解中获取指定类型的注解