Skip to content

Java 反射 API

是什么

Java 反射允许程序在运行时查询并操纵类、字段、方法、注解等元信息。本框架里需要掌握 4 个 API:

API用途
Class<?>类型的运行时代表,所有反射的入口
Class#getDeclaredFields()拿到本类声明的所有字段(含 private,不含父类)
java.lang.reflect.Field字段的运行时代表,可读注解、读值、改值
AnnotatedElementClass / Field / Method 等共同实现的接口,统一暴露 getAnnotation(...)

getDeclaredFields vs getFields

  • getFields() 只返回 public 字段,包含父类
  • getDeclaredFields() 返回本类全部字段(含 private),不含父类

本框架业务字段大多是 private,所以选 getDeclaredFields();目前不支持继承,与“不递归父类”的语义一致。

怎么用

java
for (Field f : User.class.getDeclaredFields()) {
    // 跳过 static
    if (Modifier.isStatic(f.getModifiers())) continue;

    // 读注解
    MyAnno anno = f.getAnnotation(MyAnno.class);

    // 字段名 & 类型
    String name = f.getName();
    Class<?> type = f.getType();
}

判断字段类型时常用 type.isPrimitive() 区分基本类型,type == String.class 这种精确等值判断比 instanceof 更适合“按类型查表”。

本框架怎么用

DdlInitializer#parseFieldsbuildFieldDefinition 就是上面套路的实战:

java
for (java.lang.reflect.Field reflectField : clazz.getDeclaredFields()) {
    if (Modifier.isStatic(reflectField.getModifiers())) continue;
    FieldDefinition definition = buildFieldDefinition(reflectField);
    if (definition != null) list.add(definition);
}

buildFieldDefinition 内部:

java
Field field = reflectField.getAnnotation(Field.class);
Field.Advanced advanced = reflectField.getAnnotation(Field.Advanced.class);
Class<?> javaType = reflectField.getType();
boolean nullable = !javaType.isPrimitive();

→ 详细流程见 《扫描机制》