探索 Java 中 `Class.java` 的属性与方法

简介: 探索 Java 中 `Class.java` 的属性与方法

Java 中的 java.lang.Class 类作为所有类和接口的元数据容器,提供了丰富的属性和方法以供开发者进行反射操作、类型检查等。本文将详细阐述 Class 类的主要属性和方法,并通过示例进行说明。

属性概览

以下是一些 Class 类的关键属性

  • name: 字符串类型,表示类或接口的全限定名(如 java.lang.String)。
  • classLoader: ClassLoader 类型,代表加载该类的类加载器。
  • allPermDomain: ProtectionDomain 类型,存储类的保护域信息,与安全策略相关。
  • useCaches: 布尔类型,指示是否使用缓存来优化某些反射操作。
  • reflectionData: ReflectionData 类型,内部类,存储有关类的反射数据,如方法、字段、注解等。
  • classRedefinedCount: 整形,记录类被重新定义的次数,用于检测类定义变化。
  • genericInfo: 与泛型相关的内部类实例,存储泛型信息。
  • serialVersionUID: 长整型,类的序列化版本标识符。
  • serialPersistentFields: ObjectStreamField 数组,表示需要序列化的持久化字段。
  • reflectionFactory: ReflectionFactory 类型,提供创建反射对象(如 ConstructorMethod 等)的方法。
  • initted: 布尔类型,指示类是否已初始化。
  • enumConstants: 枚举常量数组,仅对枚举类有效。
  • enumConstantDirectory: 内部类实例,用于快速查找枚举常量。
  • annotationData: 存储类及其成员注解的内部类实例。
  • annotationType: 对于注解类,存储其对应的 Class 对象。
  • classValueMap: 存储 ClassValue 对象,用于高效地根据类计算相关值。

方法详解

以下列举并解释 Class 类的部分重要方法:

类加载与实例化
  • forName(String className): 根据类名加载类并返回对应的 Class 对象,抛出异常处理类加载失败。
  • forName0(String name, boolean initialize, ClassLoader loader, Class<?> caller): 内部方法,实际执行 forName()
  • newInstance(): 创建并初始化该类的一个新实例,通常用于非抽象类且具有默认构造器的情况。
类型判断与转换
  • isInstance(Object obj): 判断给定对象是否为该类的实例。
  • isAssignableFrom(Class<?> cls): 判断指定类是否可赋值给当前类(即是否为其子类或实现类)。
  • isInterface(): 判断是否为接口。
  • isArray(): 判断是否为数组类。
  • isPrimitive(): 判断是否为基本类型或 void。
  • isAnnotation(): 判断是否为注解类型。
  • isSynthetic(): 判断是否为编译器生成的合成类或方法。
获取类信息
  • getName(): 获取类或接口的全限定名。
  • getSimpleName(): 获取类或接口的简单名称(不包含包名)。
  • getTypeName(): 获取符合 Java 语言规范的类型名称。
  • getCanonicalName(): 获取类或接口的规范名称,对于匿名类或本地类可能返回 null
  • getPackage(): 获取包含该类的包对象。
  • getSuperclass(): 获取父类的 Class 对象。
  • getGenericSuperclass(): 获取带有泛型信息的父类类型。
  • getInterfaces(): 获取当前类实现的所有接口的 Class 对象数组。
  • getGenericInterfaces(): 获取带有泛型信息的接口类型数组。
  • getComponentType(): 对于数组类,获取其元素类型。
  • getModifiers(): 获取类或接口的修饰符(如 publicabstract 等)。
  • getSigners(): 获取类的签名者信息,通常为空。
  • setSigners(Object[] signers): 设置类的签名者信息。
反射操作
  • getEnclosingMethod(): 获取嵌套类或局部类所封闭的方法。
  • getEnclosingConstructor(): 获取嵌套类所封闭的构造函数。
  • getDeclaringClass(): 获取声明当前类或接口的类。
  • getEnclosingClass(): 获取嵌套类或局部类所封闭的类。
  • getClasses(): 获取当前类及其父类中所有公共类(包括嵌套类)的 Class 对象数组。
  • getFields(): 获取当前类及其父类中所有公共字段的 Field 对象数组。
  • getMethods(): 获取当前类及其父类中所有公共方法的 Method 对象数组。
  • getConstructors(): 获取当前类的所有公共构造函数的 Constructor 对象数组。
  • getField(String name): 根据字段名获取特定公共字段的 Field 对象。
  • getMethod(String name, Class<?>... parameterTypes): 根据方法名和参数类型获取特定公共方法的 Method 对象。
  • getConstructor(Class<?>... parameterTypes): 根据参数类型获取特定公共构造函数的 Constructor 对象。
声明成员访问
  • getDeclaredClasses(): 获取当前类中所有声明的类(包括私有嵌套类)的 Class 对象数组。
  • getDeclaredFields(): 获取当前类中所有声明的字段(包括私有字段)的 Field 对象数组。
  • getDeclaredMethods(): 获取当前类中所有声明的方法(包括私有方法)的 Method 对象数组。
  • getDeclaredConstructors(): 获取当前类中所有声明的构造函数(包括私有构造函数)的 Constructor 对象数组。
  • getDeclaredField(String name): 根据字段名获取特定声明字段的 Field 对象。
  • getDeclaredMethod(String name, Class<?>... parameterTypes): 根据方法名和参数类型获取特定声明方法的 Method 对象。
  • getDeclaredConstructor(Class<?>... parameterTypes): 根据参数类型获取特定声明构造函数的 Constructor 对象。
其他方法
  • getResourceAsStream(String name): 根据相对路径获取类资源的输入流。
  • getResource(String name): 获取类资源的 URL。
  • getProtectionDomain(): 获取类的保护域。
  • getAnnotation(Class<T> annotationClass): 获取类上指定注解类型的实例。
  • isAnnotationPresent(Class<? extends Annotation> annotationClass): 判断类上是否存在指定注解类型。
  • getAnnotations(): 获取类上所有注解的数组。
  • getDeclaredAnnotations(): 获取类上所有声明注解的数组。

示例

import java.lang.reflect.Method;

public class ClassDemo {
    public static void main(String[] args) throws Exception {
        // 类加载与实例化
        Class<String> stringClass = Class.forName("java.lang.String");
        String instance = stringClass.newInstance();

        // 类型判断与转换
        System.out.println(stringClass.isInstance(instance)); // 输出: true
        System.out.println(String.class.isAssignableFrom(stringClass)); // 输出: true

        // 获取类信息
        System.out.println(stringClass.getName()); // 输出: java.lang.String
        System.out.println(stringClass.getSimpleName()); // 输出: String
        System.out.println(stringClass.getSuperclass()); // 输出: class java.lang.Object

        // 反射操作
        Method lengthMethod = stringClass.getMethod("length");
        System.out.println(lengthMethod.invoke(instance)); // 输出: 0

        // 注解操作
        if (stringClass.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation myAnnotation = stringClass.getAnnotation(MyAnnotation.class);
            System.out.println(myAnnotation.value());
        }
    }
}

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {
    String value();
}

以上便是对 Java Class 类主要属性和方法的详细介绍,涵盖了类加载、类型判断、反射操作、注解处理等多个方面。通过熟练掌握这些内容,开发者能够更深入地理解和利用 Java 反射机制,实现灵活而强大的程序设计。

相关文章
|
14天前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
54 4
|
25天前
|
Java API
Java 对象释放与 finalize 方法
关于 Java 对象释放的疑惑解答,以及 finalize 方法的相关知识。
45 17
|
18天前
|
Java 测试技术 Maven
Java一分钟之-PowerMock:静态方法与私有方法测试
通过本文的详细介绍,您可以使用PowerMock轻松地测试Java代码中的静态方法和私有方法。PowerMock通过扩展Mockito,提供了强大的功能,帮助开发者在复杂的测试场景中保持高效和准确的单元测试。希望本文对您的Java单元测试有所帮助。
34 2
|
26天前
|
Java 开发者
在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口
【10月更文挑战第20天】在Java多线程编程中,创建线程的方法有两种:继承Thread类和实现Runnable接口。本文揭示了这两种方式的微妙差异和潜在陷阱,帮助你更好地理解和选择适合项目需求的线程创建方式。
19 3
|
26天前
|
Java 开发者
在Java多线程编程中,选择合适的线程创建方法至关重要
【10月更文挑战第20天】在Java多线程编程中,选择合适的线程创建方法至关重要。本文通过案例分析,探讨了继承Thread类和实现Runnable接口两种方法的优缺点及适用场景,帮助开发者做出明智的选择。
16 2
|
26天前
|
安全 Java
Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧
【10月更文挑战第20天】Java多线程通信新解:本文通过生产者-消费者模型案例,深入解析wait()、notify()、notifyAll()方法的实用技巧,包括避免在循环外调用wait()、优先使用notifyAll()、确保线程安全及处理InterruptedException等,帮助读者更好地掌握这些方法的应用。
17 1
|
26天前
|
Java 开发者
Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点
【10月更文挑战第20天】Java多线程初学者指南:介绍通过继承Thread类与实现Runnable接口两种方式创建线程的方法及其优缺点,重点解析为何实现Runnable接口更具灵活性、资源共享及易于管理的优势。
31 1
|
26天前
|
Java
在Java多线程编程中,`wait()`和`notify()`方法的相遇如同一场奇妙的邂逅
在Java多线程编程中,`wait()`和`notify()`方法的相遇如同一场奇妙的邂逅。它们用于线程间通信,使线程能够协作完成任务。通过这些方法,生产者和消费者线程可以高效地管理共享资源,确保程序的有序运行。正确使用这些方法需要遵循同步规则,避免虚假唤醒等问题。示例代码展示了如何在生产者-消费者模型中使用`wait()`和`notify()`。
24 1
|
26天前
|
安全 Java 开发者
Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用
本文深入解析了Java多线程中的`wait()`、`notify()`和`notifyAll()`方法,探讨了它们在实现线程间通信和同步中的关键作用。通过示例代码展示了如何正确使用这些方法,并分享了最佳实践,帮助开发者避免常见陷阱,提高多线程程序的稳定性和效率。
34 1
|
20天前
|
Java Spring
JAVA获取重定向地址URL的两种方法
【10月更文挑战第17天】本文介绍了两种在Java中获取HTTP响应头中的Location字段的方法:一种是使用HttpURLConnection,另一种是使用Spring的RestTemplate。通过设置连接超时和禁用自动重定向,确保请求按预期执行。此外,还提供了一个自定义的`NoRedirectSimpleClientHttpRequestFactory`类,用于禁用RestTemplate的自动重定向功能。