【反射】Class类

Class类中包含了类定义的详细信息,可以使用Class类中提供的方法来获取,下面我们先获取Class对象,再介绍Class类中提供的获取类信息的方法。

一、准备工作

在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() { }
}

二、获取Class对象的三种方式

在src/test/java目录的cn.horse.reflect包下新建GetClassInstanceTests测试类

GetClassInstanceTests类:

package cn.horse.reflect;

import cn.horse.reflect.entity.UserInfoEntity;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class GetClassInstanceTests {

    @Test
    public void testGetClassInstanceByBusObjectInstance() {
        assertThat(new UserInfoEntity(1L).getClass()).isNotNull();
    }

    @Test
    public void testGetClassInstanceByBusClass() {
        assertThat(UserInfoEntity.class).isNotNull();
    }

    @Test
    public void testGetClassInstanceByName() throws ClassNotFoundException {
        assertThat(Class.forName("cn.horse.reflect.entity.UserInfoEntity", false, this.getClass().getClassLoader())).isNotNull();
    }

    @Test
    public void testClassInstanceEquals() throws ClassNotFoundException {
        Class forNameType = Class.forName("cn.horse.reflect.entity.UserInfoEntity", false, this.getClass().getClassLoader());
        Class dotClassType = UserInfoEntity.class;
        Class objectGetClassType = new UserInfoEntity(1L).getClass();
        assertThat(forNameType).isEqualTo(dotClassType);
        assertThat(dotClassType).isEqualTo(objectGetClassType);
        assertThat(forNameType).isEqualTo(objectGetClassType);
    }
}

单元测试方法介绍:

testGetClassInstanceByBusObjectInstance使用对象的实例获取Class对象

testGetClassInstanceByBusClass使用类获取Class对象

testGetClassInstanceByName使用全限类名获取Class对象

testClassInstanceEquals判断三种方法获取到的Class对象是否相等

单元测试中使用了三种方式获取Class对象,三种方式获取到的Class对象是相等的。

三、Class类中方法的使用

在src/test/java目录的cn.horse.reflect包下新建ClassInstanceMethodTests测试类

ClassInstanceMethodTests类:

package cn.horse.reflect;

import cn.horse.reflect.entity.BaseEntity;
import cn.horse.reflect.entity.UserInfoEntity;
import org.junit.jupiter.api.Test;

import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Locale;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;

public class ClassInstanceMethodTests {

    @Test
    public void testGetName() {
        assertThat(UserInfoEntity.class.getSimpleName()).isEqualTo("UserInfoEntity");
        assertThat(UserInfoEntity.class.getName()).isEqualTo("cn.horse.reflect.entity.UserInfoEntity");
        assertThat(UserInfoEntity.class.getPackage().getName()).isEqualTo("cn.horse.reflect.entity");
    }

    @Test
    public void testPrimitive() {
        assertThat(byte.class.isPrimitive()).isTrue();
        assertThat(short.class.isPrimitive()).isTrue();
        assertThat(int.class.isPrimitive()).isTrue();
        assertThat(long.class.isPrimitive()).isTrue();
        assertThat(float.class.isPrimitive()).isTrue();
        assertThat(double.class.isPrimitive()).isTrue();
        assertThat(boolean.class.isPrimitive()).isTrue();
        assertThat(void.class.isPrimitive()).isTrue();
        assertThat(int[].class.isPrimitive()).isFalse();
        assertThat(String.class.isPrimitive()).isFalse();
        assertThat(UserInfoEntity.class.isPrimitive()).isFalse();
    }

    @Test
    public void testArray() {
        assertThat(String[].class.isArray()).isTrue();
        assertThat(String[].class.getComponentType()).isEqualTo(String.class);
    }

    @Test
    public void testEnum() {
        assertThat(Locale.Category.class.isEnum()).isTrue();
        Collection enumConstantList = Arrays.asList(Locale.Category.class.getEnumConstants());
        List expectedEnumConstantList = Arrays.asList(Locale.Category.values());
        assertThat(enumConstantList.size()).isEqualTo(expectedEnumConstantList.size());
        assertThat(enumConstantList).containsAll(expectedEnumConstantList);
    }

    @Test
    public void testAnnotation() {
        assertThat(SuppressWarnings.class.isAnnotation()).isTrue();
    }

    @Test
    public void testLocalClass() {
        // 定义局部类
        class LocalClass {
        }
        assertThat(LocalClass.class.isLocalClass()).isTrue();
    }

    @Test
    public void testAnonymousClass() {
        Runnable unknownClass = new Runnable() {
            @Override
            public void run() {
            }
        };
        assertThat(unknownClass.getClass().isAnonymousClass()).isTrue();
    }

    @Test
    public void testMemberClass() {
        assertThat(UserInfoEntity.class.isMemberClass()).isFalse();
        assertThat(InnerClass.class.isMemberClass()).isTrue();
        assertThat(StaticInnerClass.class.isMemberClass()).isTrue();

        // 定义局部类
        class LocalClass {
        }
        assertThat(LocalClass.class.isMemberClass()).isFalse();

        // 匿名类
        Runnable unknownClass = new Runnable() {
            @Override
            public void run() {
            }
        };
        assertThat(unknownClass.getClass().isMemberClass()).isFalse();
    }

    @Test
    public void testGetModifiers() {
        assertThat(Modifier.isPublic(UserInfoEntity.class.getModifiers())).isTrue();
        assertThat(Modifier.isProtected(UserInfoEntity.class.getModifiers())).isFalse();
        assertThat(Modifier.isPrivate(UserInfoEntity.class.getModifiers())).isFalse();
        assertThat(Modifier.isAbstract(UserInfoEntity.class.getModifiers())).isFalse();
        assertThat(Modifier.isInterface(UserInfoEntity.class.getModifiers())).isFalse();
        assertThat(Modifier.isStatic(UserInfoEntity.class.getModifiers())).isFalse();
        assertThat(Modifier.isFinal(UserInfoEntity.class.getModifiers())).isFalse();
        assertThat(Modifier.isNative(UserInfoEntity.class.getModifiers())).isFalse();
    }

    @Test
    public void testStaticInnerClass() {
        assertThat(Modifier.isStatic(StaticInnerClass.class.getModifiers())).isTrue();
    }

    @Test
    public void testInnerClass() {
        assertThat(InnerClass.class.isMemberClass() && !Modifier.isStatic(InnerClass.class.getModifiers())).isTrue();
    }

    private static class StaticInnerClass { }
    private class InnerClass { }

    @Test
    public void testTypeConvert() {
        assertThat(UserInfoEntity.class.isInstance(new UserInfoEntity(1L))).isTrue();
        assertThat(BaseEntity.class.isInstance(new UserInfoEntity(1L))).isTrue();
        assertThat(UserInfoEntity.class.isAssignableFrom(UserInfoEntity.class)).isTrue();
        assertThat(BaseEntity.class.isAssignableFrom(UserInfoEntity.class)).isTrue();
        assertThat(BaseEntity.class.cast(new UserInfoEntity(1L))).isNotNull();
        assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> BaseEntity.class.cast(1));
    }
}

单元测试类中定义了两个内部类:静态内部类StaticInnerClass、内部类InnerClass;

单元测试方法介绍:

testGetName获取类名称,其中getSimpleName用于获取简略名称,getName用于获取全限类名,getPackage用于获取包对象

testPrimitive判断是否是基本数据类型,使用isPrimitive方法判断是否是基本数据类型(byte,short,int,long,float,double,Boolean,void)

testArray判断并获取数组元素类型,使用isArray判断是否是数组类型,使用getComponentType获取数组元素类型

testEnum判断并获取枚举常量数组,使用isEnum判断是否是枚举类型,使用getEnumConstants获取枚举常量数组

testAnnotation判断是否是注解类型,使用isAnnotation判断是否是注解类型

testLocalClass判断是否是局部类,使用isLocalClass判断是否是局部类

testAnonymousClass判断是否是匿名类,使用isAnonymousClass判断是否是匿名类

testMemberClass判断是否是成员类,使用isMemberClass判断是否是成员类,内部类、静态内部类都属于成员类,局部类、匿名类都不属于成员类

testGetModifiers获取修饰符,使用getModifiers获取修饰符,并使用Modifier类提供的静态方法依次判断了是否使用了public、protected、private、abstract、interface、static、final、native等修饰符

testStaticInnerClass判断是否是静态内部类,使用getModifiers获取修饰符,并使用Modifier类提供的静态方法判断是否使用了static修饰符

testInnerClass判断是否是内部类,判断是否是成员类并且没有使用static修饰符

testTypeConvert类型判断与转换,使用isInstance或isAssignableFrom可以判断类型是否可以转换,使用cast可以进行类型的转换。

你可能感兴趣的:(#,反射,java)