搜索 K
Appearance
Appearance
Java 反射允许程序在运行时查询并操纵类、字段、方法、注解等元信息。本框架里需要掌握 4 个 API:
| API | 用途 |
|---|---|
Class<?> | 类型的运行时代表,所有反射的入口 |
Class#getDeclaredFields() | 拿到本类声明的所有字段(含 private,不含父类) |
java.lang.reflect.Field | 字段的运行时代表,可读注解、读值、改值 |
AnnotatedElement | Class / Field / Method 等共同实现的接口,统一暴露 getAnnotation(...) |
getDeclaredFields vs getFields
getFields() 只返回 public 字段,包含父类getDeclaredFields() 返回本类全部字段(含 private),不含父类本框架业务字段大多是 private,所以选 getDeclaredFields();目前不支持继承,与“不递归父类”的语义一致。
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#parseFields 与 buildFieldDefinition 就是上面套路的实战:
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 内部:
Field field = reflectField.getAnnotation(Field.class);
Field.Advanced advanced = reflectField.getAnnotation(Field.Advanced.class);
Class<?> javaType = reflectField.getType();
boolean nullable = !javaType.isPrimitive();→ 详细流程见 《扫描机制》