Java中的反射:如何窥视代码内部并操控它

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Java中的反射与内省:人人都能掌握的魔法

\n\n

想象一下,你是一位程序员,正在编写能够在运行时分析自身的代码。听起来像科幻小说?在Java中,这是现实,它被称为反射(Reflection)。

\n\n

当我第一次在Java中遇到反射时,它的强大力量让我震惊。想象一下:你可以通过名称加载一个类,了解它的所有方法和字段,甚至可以调用作者本想隐藏的私有方法。这就像拿到了建筑中所有门的钥匙。很酷吧?毫无疑问。很危险?同样是的。

\n\n

在本文中,我们将探讨什么是Java中的反射与内省,它们如何工作,以及——最重要的是——如何明智地使用它们。会有大量代码、示例和实用技巧。我们开始吧!

\n\n

用简单的话说,Java中的反射是什么

\n\n

Java中的反射是一种机制,它允许程序在运行时获取关于类、接口、方法和字段的信息。此外,通过反射,可以创建对象、调用方法以及修改字段的值,即使它们是私有的。

\n\n

那么什么是Java中的内省?它是反射的一部分,专门负责“窥探”:获取类的结构信息而不修改它。内省是分析,反射是分析加行动。

\n\n

这一切的基础是java.lang.Class类。它就像是任何对象的“护照”。当JVM加载一个类时,它会创建一个Class对象,该对象存储了所有的元信息。

\n\n

如何获取Class对象:三种方法

\n\n

在使用反射施展魔法之前,需要获取Class对象。以下是三种主要方法:

\n\n
// 1. 通过 .class
Class<String> stringClass = String.class;

// 2. 通过对象的 getClass()
String hello = "你好";
Class<? extends String> helloClass = hello.getClass();

// 3. 通过 Class.forName()(最灵活)
try {
    Class<?> dynamicClass = Class.forName("java.util.ArrayList");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
\n\n

第三种方法在类名在编译时未知时特别有用——例如,它来自配置文件或数据库。

\n\n

内省:窥视类的内部

\n\n

让我们编写一个小类,看看通过Java中的内省可以了解它的哪些信息。

\n\n
import java.lang.reflect.*;

public class ReflectionDemo {
    
    private String secret = "这是一个秘密!";
    public int number = 42;
    
    public void publicMethod() {
        System.out.println("公有方法");
    }
    
    private void privateMethod() {
        System.out.println("私有方法");
    }
    
    public static void main(String[] args) throws Exception {
        // 获取Class对象
        Class<?> demoClass = Class.forName("ReflectionDemo");
        
        System.out.println("=== 类名 ===");
        System.out.println(demoClass.getName());
        
        System.out.println("\\n=== 所有字段 ===");
        Field[] fields = demoClass.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName() + " : " + field.getType().getSimpleName());
        }
        
        System.out.println("\\n=== 所有方法 ===");
        Method[] methods = demoClass.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName() + "()");
        }
        
        System.out.println("\\n=== 构造方法 ===");
        Constructor<?>[] constructors = demoClass.getDeclaredConstructors();
        for (Constructor<?> constructor : constructors) {
            System.out.println(constructor);
        }
    }
}
\n\n

运行这段

博客

书籍推荐