Class相关api介绍

版本约定

本篇基于java17版本写的

api一览

1. 获取类信息的方法

这些方法用于获取类本身的信息,例如类名、修饰符、包等。

getName():返回类的全限定名(包括包名)。

• getSimpleName():返回类的简单名称(不包括包名)。

• getCanonicalName():返回类的规范名称,如果类没有规范名称则返回 null。

• getModifiers():返回类的修饰符(如 public、private、abstract 等),以 int 值表示。

• getPackage():返回该类所属的包。

• getSuperclass():返回该类的直接父类的 Class 对象。

• getInterfaces():返回该类实现的所有接口的 Class 数组。

• isInterface():判断该 Class 对象是否表示一个接口。

• isEnum():判断该 Class 对象是否表示一个枚举类型。

• isAnnotation():判断该 Class 对象是否表示一个注解类型。

• isArray():判断该 Class 对象是否表示一个数组类型。

• isPrimitive():判断该 Class 对象是否表示一个基本类型(如 int、boolean 等)。

2. 获取类成员(字段、方法、构造函数)的方法

这些方法用于获取类中的字段、方法、构造函数等成员信息。

• getFields():返回所有 public 字段(包括父类继承的)。

• getDeclaredFields():返回所有字段(仅包括本类声明的,且不论访问修饰符)。

• getField(String name):返回指定名称的 public 字段。

• getDeclaredField(String name):返回指定名称的字段(不论修饰符)。

• getMethods():返回所有 public 方法(包括继承的)。

• getDeclaredMethods():返回所有声明的方法(包括 private 和 protected,但不包括父类的方法)。

• getMethod(String name, Class<?>… parameterTypes):返回指定名称和参数类型的 public 方法。

• getDeclaredMethod(String name, Class<?>… parameterTypes):返回指定名称和参数类型的方法(不论修饰符)。

• getConstructors():返回所有 public 构造函数。

• getDeclaredConstructors():返回所有声明的构造函数(包括 private 构造函数)。

• getConstructor(Class<?>… parameterTypes):返回指定参数类型的 public 构造函数。

• getDeclaredConstructor(Class<?>… parameterTypes):返回指定参数类型的构造函数(不论修饰符)。

3. 操作类成员的方法

这些方法用于通过反射调用类中的字段、方法、构造函数等。

• getField(String name) 和 getDeclaredField(String name) 返回的 Field 对象可以用于读取或修改字段的值。

  • Field.get(Object obj):获取对象的字段值。
  • Field.set(Object obj, Object value):设置对象的字段值。

• getMethod(String name, Class<?>… parameterTypes) 和 getDeclaredMethod(String name, Class<?>… parameterTypes) 返回的 Method 对象可以用于调用方法。

  • Method.invoke(Object obj, Object… args):调用对象的方法。

• getConstructor(Class<?>… parameterTypes) 和 getDeclaredConstructor(Class<?>… parameterTypes) 返回的 Constructor 对象可以用于创建对象。

  • Constructor.newInstance(Object… initargs):通过构造函数创建对象。

4. 类型检查和类型转换的方法

这些方法用于检查类的类型、类之间的继承关系,以及进行安全的类型转换。

• isInstance(Object obj):判断某个对象是否是该类的实例,等同于 instanceof 操作符。

• isAssignableFrom(Class<?> cls):判断该类是否是指定类的父类或接口,等同于 cls instanceof Class<?> 的形式。

• cast(Object obj):将指定对象转换为该类的类型,等同于强制类型转换 (ClassType) obj。

• asSubclass(Class<U> clazz):将当前 Class 对象表示的类转换为指定的子类。

5. 数组相关的方法

这些方法用于操作数组类型的类。

• getComponentType():如果当前 Class 对象表示一个数组,则返回数组元素的类型。

• arrayType():用于表示数组类型的 Class 对象。

6. 注解相关的方法

这些方法用于获取类上的注解信息。

• getAnnotations():返回该类上的所有注解。

• getDeclaredAnnotations():返回该类上声明的注解(不包括父类中的注解)。

• getAnnotation(Class<T> annotationClass):返回指定类型的注解。

• isAnnotationPresent(Class<? extends Annotation> annotationClass):判断该类是否带有指定的注解。

7. 类加载和反射相关的辅助方法

这些方法用于辅助类的加载、反射操作或判断。

• forName(String className):返回指定类名的 Class 对象。

• getClassLoader():返回加载当前类的类加载器。

• desiredAssertionStatus():返回类的断言状态。

• getProtectionDomain():返回类的保护域,主要用于安全管理。

方法返回值类型适用场景
getCanonicalName()规范名称(带包名和点号的嵌套类名)获取类的规范名,适用于非匿名类、局部类的场景
getSimpleName()简单名称(类名,不带包名)获取类的短名称,适用于显示、日志等场景
getName()全限定名称(包名+类名,用 $$ 表示内部类)获取类的内部名称,适用于反射、序列化等需要全名的场景,包含匿名类和局部类名
getTypeName()类型名称(更人性化的名称)获取类的类型名称,对数组、泛型类型友好,适合显示和日志用途

api测试

定义几个类来辅助测试

public interface InterfaceClass<T> {
}

public class Level0Class<T> implements InterfaceClass<T> {
}


public class Level1Class<T> extends Level0Class<List<T>> implements InterfaceClass<List<T>> {



    public Object c;

    public Level1Class() {
		// 本地类
        class ClassA {
        }
        c = new ClassA();
    }

    public Object getC() {
        return c;
    }

    public Object classAObject() {
        class ClassA {
        }
        return new ClassA();
    }

    public static class InnerClass{}
}

public class OuterClass {
    // 公共成员类
    public class PublicInnerClass {}

    // 私有成员类
    private class PrivateInnerClass {}

    // 公共静态嵌套类
    public static class PublicStaticNestedClass {}

    // 私有静态嵌套类
    private static class PrivateStaticNestedClass {}

    // 公共接口
    public interface PublicInterface {}

    // 私有接口
    private interface PrivateInterface {}
}

isA的判断

@Test
    void isATest() {
        Class<String> stringClass = String.class;
        String str = "Hello";
        // A.isInstance(B) 判断B是否为A的实例
        System.out.println(stringClass.isInstance(str));    // true
//        System.out.println(String.class.isInstance(str));    // true

        Class<Number> numberClass = Number.class;
        Class<Integer> integerClass = Integer.class;
        // A.isAssignableFrom(B)  判断B是否的实例是否为赋值给A; 也就是 ? extends A  B就是这个?
        System.out.println(numberClass.isAssignableFrom(integerClass)); // true

        // 判断A是否为B的实例
        System.out.println(str instanceof String);  // true
    }

isSynthetic判断动态类

/**
     * 判断一个类是否为动态生成的类
     */
    @Test
    void isSyntheticTest() {
        Runnable r = () -> System.out.println("hello");
        System.out.println("是否为编译器自动生成的类:" + r.getClass().isSynthetic()); // true
        System.out.println("是否为编译器自动生成的类:" + TempClass.class.isSynthetic());  // false

        Function<String, String> func = String::valueOf;
        System.out.println("是否为编译器自动生成的类:" + func.getClass().isSynthetic()); // true
        Consumer<String> aa = this::say;
        System.out.println("是否为编译器自动生成的类:" + aa.getClass().isSynthetic()); // true
    }

private void say(String a) {
    }

获取泛型类型

/**
     * 获取类声明中定义的泛型类型参数
     */
    @Test
    void getTypeParametersTest() {
        // 获取类声明中定义的泛型类型参数
        TypeVariable<Class<Level1Class>>[] typeParameters = Level1Class.class.getTypeParameters();
        System.out.println(typeParameters[0].getName());    // T
        // getGenericDeclaration: 获取类型变量声明的位置; 例如Level1Class<T>中T声明在Level1Class中, 它可以是 Class、Method 或 Constructor,用于获取声明泛型的上下文
        System.out.println(typeParameters[0].getGenericDeclaration().getSimpleName());    // Level1Class
        System.out.println(typeParameters[0].getTypeName());    // T
    }

获取直接继承的泛型父类

/**
     * 返回当前类的直接父类的泛型类型; 注意: 是直接父类
     */
    @Test
    void getGenericSuperclassTest() {
        // per.qiao.myutils.clazz.Level0Class<java.util.List<T>>
        System.out.println(Level1Class.class.getGenericSuperclass());
        // per.qiao.myutils.clazz.Level0Class<java.util.List<T>>
        System.out.println(Level1Class.class.getGenericSuperclass().getTypeName());
        // class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
        System.out.println(Level1Class.class.getGenericSuperclass().getClass());
    }

方法中的本地类

/**
     * 返回类所在的直接方法;(类是在哪个方法中定义的)
     */
    @Test
    void getEnclosingMethodTest() {
        Class c = (new Level1Class()).classAObject().getClass();
        // public java.lang.Object per.qiao.myutils.clazz.Level1Class.classAObject()
        System.out.println(c.getEnclosingMethod());

        // class per.qiao.myutils.clazz.Level1Class
        System.out.println("宿主:" + c.getNestHost());

        Class c1 = new Level1Class().getC().getClass();
        System.out.println(c1.getEnclosingMethod());    // null
    }

构造器中的本地类

/**
     * 返回类所在的直接构造器;(类是在哪个构造器中定义的)
     */
    @Test
    void getEnclosingConstructorTest() {
        Class c = new Level1Class().getC().getClass();
        // 宿主:class per.qiao.myutils.clazz.Level1Class
        System.out.println("宿主:" + c.getNestHost());
        // public per.qiao.myutils.clazz.Level1Class()
        System.out.println(c.getEnclosingConstructor());
    }

内部类判断

/**
     * 返回当前类是哪个类的内部类(即嵌套类)的情况。如果当前类是某个类的内部类,getDeclaringClass() 方法将返回该外部类的 Class 对象;如果当前类不是内部类,则返回 null。
     * 注意: 不包括匿名类和局部类;
     */
    @Test
    void getDeclaringClassTest() {
        Class<?> declaringClass = Level1Class.InnerClass.class.getDeclaringClass();
        System.out.println("InnerClass定义所在类为:" + declaringClass);//class per.qiao.myutils.clazz.Level1Class
        // class per.qiao.myutils.clazz.Level1Class
        System.out.println("宿主:" + declaringClass.getNestHost());
        System.out.println(declaringClass.getEnclosingClass()); // null
    }

/**
     * 返回当前类是哪个类的内部类-包括匿名类和局部类;
     */
    @Test
    void getEnclosingClassTest() {
        // class per.qiao.myutils.clazz.Level1Class
        System.out.println(Level1Class.InnerClass.class.getEnclosingClass());

        Class c = (new Level1Class()).classAObject().getClass();
        // class per.qiao.myutils.clazz.Level1Class
        System.out.println(c.getEnclosingClass());
    }

类名称


/**
     * getName, getCanonicalName, getSimpleName, getTypeName
     */
    @Test
    void nameTest() {
        int[] arr = {0};

        // 返回类的完全限定名,如果类是匿名类或局部类,或者类没有规范名称,则返回 null。;
        // per.qiao.myutils.clazz.Level1Class
        System.out.println(Level1Class.class.getCanonicalName());
        // 局部类
        Class c = (new Level1Class()).classAObject().getClass();
        System.out.println(c.getCanonicalName());   // null
        System.out.println(arr.getClass().getCanonicalName());   // int[]

        // Level1Class
        System.out.println(Level1Class.class.getSimpleName());
        System.out.println(arr.getClass().getSimpleName());   // int[]

        // 返回类的完全限定名;
        // per.qiao.myutils.clazz.Level1Class
        System.out.println(Level1Class.class.getName());
        // 对于匿名类或局部类,也能返回类的名称。
        System.out.println(c.getName());   // per.qiao.myutils.clazz.Level1Class$1
        // 对于数组类型,返回的是内部表示法,如[Ljava.lang.String、[I
        System.out.println(arr.getClass().getName());   // [I

        // per.qiao.myutils.clazz.Level1Class
        System.out.println(Level1Class.class.getTypeName());
        // per.qiao.myutils.clazz.Level0Class<java.util.List<T>>
        System.out.println(Level1Class.class.getGenericSuperclass().getTypeName());
        System.out.println(arr.getClass().getTypeName());   // int[]
    }

匿名类判断

/**
     * 判断是否为匿名类
     */
    @Test
    void isAnonymousClassTest() {
        // 方法内部类
        Class c = (new Level1Class()).classAObject().getClass();
        System.out.println(c.isAnonymousClass());   // false

        Runnable r = new Runnable() {
            @Override
            public void run() {}
        };
        System.out.println(r.getClass().isAnonymousClass()); // true
    }

这里注意runable简写后就不是普通的匿名类了

判断本地类

/**
     * isLocalClass() 是 Class 类中的一个方法,用于判断当前类是否是一个本地类(local class)。
     * 本地类是在某个方法、构造函数或者初始化块中定义的类。
     */
    @Test
    void isLocalClassTest() {
        Class c = (new Level1Class()).classAObject().getClass();
        System.out.println(c.isLocalClass());   // true
    }

判断成员类

/**
     * 判断是否为成员类; 静态类不是成员类; 本地类也不是成员类
     */
    @Test
    void isMemberClassTest() {
        Class c = (new Level1Class()).classAObject().getClass();
        System.out.println(c.isMemberClass());  // false

        Class c1 = Level1Class.InnerClass.class;
        System.out.println(c1.isMemberClass()); // true
    }

获取成员类

/**
     * 它返回一个数组,包含当前类和父类中声明的所有公共成员类、接口、枚举类的 Class 对象。
     * 这个方法只返回公共的(public)嵌套类和接口,不包含非公共的成员类或本地类、匿名类。
     */
    @Test
    void getClassesTest() {
        Class<OuterClass> outerClassClass = OuterClass.class;
        Class<?>[] classes = outerClassClass.getClasses();
        for (Class<?> aClass : classes) {
            // interface per.qiao.myutils.clazz.OuterClass$PublicInterface
            // class per.qiao.myutils.clazz.OuterClass$PublicStaticNestedClass
            // class per.qiao.myutils.clazz.OuterClass$PublicInnerClass
            System.out.println(aClass);
        }
    }
    
    /**
     * 返回当前类中声明的所有嵌套类、接口和枚举,包括私有、受保护、包级私有等非公共类
     */
    @Test
    void getDeclaredClassesTest() {
        Class<?>[] declaredClasses = OuterClass.class.getDeclaredClasses();
        for (Class<?> clazz : declaredClasses) {
            System.out.println(clazz.getName());
        }
    }

cast

类型强转

/**
     * 类型转换, 底层通过isInstance判断
     */
    @Test
    void castTest() {
        Object obj = new Level1Class();
        // isInstance
        Level1Class cast = Level1Class.class.cast(obj);
        System.out.println(cast);
    }

asSubclass

class之间的转换

/**
     * 子转父
     */
    @Test
    void asSubclassTest() {
        boolean assignableFrom = Level0Class.class.isAssignableFrom(Level1Class.class);
        System.out.println(assignableFrom);

        Class<? extends Level0Class> subclass = Level1Class.class.asSubclass(Level0Class.class);
        System.out.println(subclass);
    }

获取宿主类

/**
     * 用于获取当前类的嵌套类的宿主类(即它的外部类)。
     * 这是与嵌套类(Nested Class)相关的一部分,特别是在处理内部类和静态嵌套类时。
     */
    @Test
    void getNestHostTest() {
        // 获取内部类的宿主类 per.qiao.myutils.clazz.OuterClass
        Class<?> innerClassHost = OuterClass.PublicInnerClass.class.getNestHost();
        System.out.println("InnerClass host: " + innerClassHost.getName());

        // 获取静态嵌套类的宿主类 per.qiao.myutils.clazz.OuterClass
        Class<?> staticNestedClassHost = OuterClass.PublicStaticNestedClass.class.getNestHost();
        System.out.println("StaticNestedClass host: " + staticNestedClassHost.getName());

        // 获取外部类的宿主类; per.qiao.myutils.clazz.OuterClass
        Class<?> outerClassHost = OuterClass.class.getNestHost();
        System.out.println("OuterClass host: " + outerClassHost);
    }

不同类判断同一宿主类

/**
     * 用于判断当前类是否与指定类是嵌套类的同伴(Nest Mate)。
     * 嵌套类同伴是指同一个外部类的嵌套类,它们可以访问彼此的私有成员。
     */
    @Test
    void isNestmateOfTest() {
        Class<?> innerClass1 = OuterClass.PublicInnerClass.class;
        Class<?> innerClass2 = OuterClass.PublicInterface.class;
        Class<?> staticNestedClass = OuterClass.PublicStaticNestedClass.class;

        // 检查两个内部类是否为同伴
        boolean isNestmate1 = innerClass1.isNestmateOf(innerClass2);
        boolean isNestmate2 = innerClass1.isNestmateOf(staticNestedClass);

        System.out.println("InnerClass1 is nestmate of InnerClass2: " + isNestmate1); // true
        System.out.println("InnerClass1 is nestmate of StaticNestedClass: " + isNestmate2); // true
    }


查询嵌套类

/**
     * 获取指定类的嵌套成员
     */
    @Test
    void getNestMembersTest() {
        Class<?>[] nestMembers = OuterClass.class.getNestMembers();
        for (Class<?> nestMember : nestMembers) {
            System.out.println(nestMember.getName());
        }
    }

类描述

/**
     * 获取类描述
     */
    @Test
    void descriptorStringTest() {
        System.out.println(Level1Class.class.descriptorString());
    }

获取数组类型

@Test
    void arrayTypeTest() {
        System.out.println(Level1Class.class.arrayType());
    }

密封类

// 密封接口
public sealed interface SealedInterface permits NonSealedSubA {
}
// 定义非密封实现
public non-sealed class NonSealedSubA implements SealedInterface {
}

// 密封类
public sealed class SealedClass permits SealedSubClass, SealedSubClass2 {
}
// 密封类的普通实现, 需要用final标识
public final class SealedSubClass extends SealedClass {
}
// 密封类的非密封实现, 需要用non-sealed标识
public non-sealed class SealedSubClass2 extends SealedClass {
}

/**
     * 获取密封类的所有允许的子类
     */
    @Test
    void getPermittedSubclassesTest() {
        Class<?>[] permittedSubclasses = SealedClass.class.getPermittedSubclasses();
        for (Class<?> permittedSubclass : permittedSubclasses) {
            // per.qiao.myutils.clazz.sealed.SealedSubClass
            // per.qiao.myutils.clazz.sealed.SealedSubClass2
            System.out.println(permittedSubclass.getName());
        }

        Class<?>[] permittedSubclasses2 = SealedInterface.class.getPermittedSubclasses();
        for (Class<?> permittedSubclass : permittedSubclasses2) {
            // per.qiao.myutils.clazz.sealed.NonSealedSubA
            System.out.println(permittedSubclass.getName());
        }
    }

    /**
     * isSealed判断一个类是不是密封类
     */
    @Test
    void isSealedTest() {
        System.out.println(SealedClass.class.isSealed());   // true
        System.out.println(SealedInterface.class.isSealed());   // true
        System.out.println(SealedSubClass2.class.isSealed());   // false
        System.out.println(NonSealedSubA.class.isSealed());   // false
    }

个人公众号
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

uncleqiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值