Просмотр исходного кода

docs: 更新20260813课堂笔记,同步代码变更——新增反射知识全景总览章节(Demo03:把整个反射体系整理成4类知识地图——Class类反射(成员属性/方法/构造,各4个获取API共12个)、Field属性反射(属性名getName/修饰符getModifiers/值get+set)、Method方法反射(方法名getName/执行invoke/返回值getReturnType/参数getParameterTypes/修饰符getModifiers)、Constructor构造反射(修饰符getModifiers/参数getParameterTypes/创建对象newInstance)、12个获取API统一规律getXxx(s)/getDeclaredXxx(s)口诀含Declared的能拿私有),同步更新笔记标题概览/目录/知识点全景总结/随堂练习要点/拓展阅读,练习五答案参考exericse/MethodPrintUtilTest.java(遍历时setAccessible(true)+Modifier.toString+字符串修复去方括号)、练习六答案参考exericse/MethodInvokeTest.java(args[i].getClass()动态计算参数类型数组),exericse/Student新增getter/setter与eat方法,同步更新README授课代码表

WanJL 2 недель назад
Родитель
Сommit
49b03de775

Разница между файлами не показана из-за своего большого размера
+ 0 - 1
README.md


+ 47 - 0
授课代码/c260813/src/course/Demo03.java

@@ -0,0 +1,47 @@
+package course;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title Demo03
+ * @description
+ * @create 2026/8/13
+ */
+public class Demo03 {
+    /*
+                如果想要弄明白反射,需要掌握以下内容:
+                    1、针对类的反射--Class-就需要记住类里面有哪些成员?
+                        |- 成员属性
+                            |- 获取一个对象:getField()
+                            |- 获取多个对象(数组):getFields()
+                            |- 获取一个私有对象:getDeclaredField()
+                            |- 获取多个私有对象:getDeclaredFields()
+                        |- 成员方法
+                            |- 获取对象:getMethod()
+                            |- 获取多个对象(数组):getMethods()
+                            |- 获取一个私有对象:getDeclaredMethod()
+                            |- 获取多个私有对象:getDeclaredMethods()
+                        |- 构造方法
+                            |- 获得对象:getConstructor()
+                            |- 获取多个对象(数组):getConstructors()
+                            |- 获取一个私有对象:getDeclaredConstructor()
+                            |- 获取多个私有对象:getDeclaredConstructors()
+                    2、针对属性的反射--Field-就需要记住属性的组成部分有哪些?
+                            |- 属性变量名    getName()
+                            |- 属性修饰符    getModifiers()
+                            |- 属性值
+                                |- 获取值 get()
+                                |- 赋值  set()
+                    3、针对方法的反射--Method-就需要记住方法的组成部分有哪些?
+                            |- 方法名称     getName()
+                            |- 执行方法     invoke()
+                            |- 方法返回值类型  getReturnType()
+                            |- 方法的参数列表类型    getParameterTypes()
+                            |- 方法的修饰符     getModifiers()
+                    4、针对构造放过的反射--Constructor--就需要记住构造方法的组成部分有哪些?
+                            |- 构造方法的修饰符     getModifiers()
+                            |- 构造方法的参数列表类型     getParameterTypes()
+                            |- 创建对象     newInstance()
+
+             */
+}

+ 46 - 0
授课代码/c260813/src/exericse/MethodInvokeTest.java

@@ -0,0 +1,46 @@
+package exericse;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title MethodInvokeTest
+ * @description
+ * @create 2026/8/13
+ */
+public class MethodInvokeTest {
+    public static void main(String[] args) throws Exception {
+        // 1. 创建 Student 对象(六参构造 name="张三")
+        Student s=new Student(1001,"张三",25);
+        // 2. 反射调用 getName() 无参方法,接收返回值强转打印
+        Object name = invokeMethod(s, "eat", "饭...");
+        System.out.println(name);
+        // 3. 反射调用 setName(String) 带参方法(void 不接收返回值)
+        // 4. 用 s.getName() 普通访问验证反射 setter 生效
+        // 5. 用封装好的 invokeMethod 工具再调用 setName
+        // 6. 打印 invokeMethod(s, "setName", "王五") 的返回值 → null(void 方法)
+    }
+
+    // 通用工具:反射调用对象 obj 的 public 方法 methodName,参数 args,返回方法执行结果
+    public static Object invokeMethod(Object obj, String methodName, Object... args) throws Exception {
+        // 1. 根据 args 动态计算参数类型数组(每个参数.getClass())
+        Class<?>[] classes=new Class[args.length];
+        for (int i=0;i<args.length;i++){
+            classes[i]=args[i].getClass();
+        }
+        Class<?> objClass = obj.getClass();
+        Method method;
+        if (args!=null){
+            // 2. getMethod(methodName, 参数类型...) 获取方法
+            method =objClass.getMethod(methodName, classes);
+            // 3. method.invoke(obj, args) 调用并返回结果
+            return method.invoke(obj,args);
+        }else {
+            method =objClass.getMethod(methodName); //无参数就不传参数的Class对象
+            return method.invoke(obj);
+        }
+    }
+
+
+}

+ 71 - 0
授课代码/c260813/src/exericse/MethodPrintUtilTest.java

@@ -0,0 +1,71 @@
+package exericse;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * @author WanJl
+ * @version 1.0
+ * @title MethodPrintUtilTest
+ * @description
+ * @create 2026/8/13
+ */
+public class MethodPrintUtilTest {
+    public static void main(String[] args) {
+        // 1. 打印 Student 的所有 public 方法(含父类 Object 继承的 toString 等)
+        //printPublicMethods(Student.class);
+        // 2. 打印 Student 的本类全部方法(含 private 的 read/write)
+        printDeclaredMethods(Student.class);
+    }
+
+    // 通用工具:打印任意类 clazz 的所有 public 方法(方法名(参数类型列表) 返回值=xxx)
+    public static void printPublicMethods(Class<?> clazz) {
+        // getMethods() 遍历  --- 根据clazz对象 获取所有的public修饰的Method方法对象
+        Method[] clazzMethods = clazz.getMethods();
+
+        //   getParameterTypes() → Arrays.stream + map(getSimpleName) + collect(List)
+        //-- 获取每个方法的参数类型数组
+        for (Method m: clazzMethods){
+            //m方法对象的参数类型数组,返回的是类型所属的Class对象
+            Class<?>[] parameterTypes = m.getParameterTypes();  //方法的参数类型数组
+            List<String> parameterTypeNames = Arrays.stream(parameterTypes).map(p -> p.getSimpleName()).collect(Collectors.toList());
+            //   getName() / getReturnType().getSimpleName() 拼接打印
+            String methodName = m.getName();    //方法名
+            String returnType = m.getReturnType().getSimpleName();
+            System.out.println(returnType+" "+methodName+"("+parameterTypeNames+")");
+        }
+    }
+
+    // 通用工具:打印任意类 clazz 的本类全部方法(含 private)
+    public static void printDeclaredMethods(Class<?> clazz) {
+        // getDeclaredMethods() 遍历,同样的打印格式
+        // getMethods() 遍历  --- 根据clazz对象 获取所有的public修饰的Method方法对象
+        Method[] clazzMethods = clazz.getDeclaredMethods();
+        //   getParameterTypes() → Arrays.stream + map(getSimpleName) + collect(List)
+        //-- 获取每个方法的参数类型数组
+        for (Method m: clazzMethods){
+            //暴力反射
+            m.setAccessible(true);
+            //m方法对象的参数类型数组,返回的是类型所属的Class对象
+            Class<?>[] parameterTypes = m.getParameterTypes();  //方法的参数类型数组
+            List<String> parameterTypeNames = Arrays.stream(parameterTypes).map(p -> p.getSimpleName()).collect(Collectors.toList());
+            //   getName() / getReturnType().getSimpleName() 拼接打印
+            String methodName = m.getName();    //方法名
+            String returnType = m.getReturnType().getSimpleName();
+            int modifiers = m.getModifiers();
+            String modifier = Modifier.toString(modifiers);
+
+            //字符串修复--干掉方括号
+            String ptn = parameterTypeNames.toString();
+            ptn=ptn.replace("[","");
+            ptn=ptn.replace("]","");
+
+            System.out.println(modifier+" "+returnType+" "+methodName+"("+ptn+")");
+
+        }
+
+    }
+}

+ 36 - 0
授课代码/c260813/src/exericse/Student.java

@@ -22,6 +22,38 @@ public class Student {
         this.age = age;
     }
 
+    public Integer getId() {
+        return id;
+    }
+
+    public void setId(Integer id) {
+        this.id = id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public Integer getAge() {
+        return age;
+    }
+
+    public void setAge(Integer age) {
+        this.age = age;
+    }
+
+    public static String getSchool() {
+        return school;
+    }
+
+    public static void setSchool(String school) {
+        Student.school = school;
+    }
+
     @Override
     public String toString() {
         return "Student{" +
@@ -33,6 +65,10 @@ public class Student {
     public void study(){
         System.out.println(this.name+"在学习");
     }
+
+    public void eat(String s){
+        System.out.println("吃:"+s);
+    }
     public static void main(String[] args) {
         Student s1 = new Student(1001, "张三", 25);
         Student s2 = new Student(1002, "李四", 30);

+ 108 - 8
课堂笔记/01-JavaSE基础-笔记/20260813-笔记.md

@@ -4,7 +4,7 @@
 - **项目**:`c260813`
 - **包路径**:`course`
 - **作者**:WanJL
-- **内容概览**:反射 Field(属性/字段/变量)(Demo01 演示:Class 类获取 Field 对象的 4 个 API → 获取所有属性并输出修饰符和类型 → 读取/修改 public 属性 → setAccessible(true) 暴力反射读取/修改 private 属性 → 操作静态属性传 null)+ 反射 Method(方法)(Demo02 演示:Class 类获取 Method 对象的 4 个 API → 遍历方法输出方法名/参数/返回值 → invoke 调用实例方法/带参方法/私有方法/静态方法)+ Student 实体类(private/public/public static 字段设计 + 4 个构造方法 + 7 组 getter/setter + 私有方法 read/write)
+- **内容概览**:反射 Field(属性/字段/变量)(Demo01 演示:Class 类获取 Field 对象的 4 个 API → 获取所有属性并输出修饰符和类型 → 读取/修改 public 属性 → setAccessible(true) 暴力反射读取/修改 private 属性 → 操作静态属性传 null)+ 反射 Method(方法)(Demo02 演示:Class 类获取 Method 对象的 4 个 API → 遍历方法输出方法名/参数/返回值 → invoke 调用实例方法/带参方法/私有方法/静态方法)+ 反射知识全景总览(Demo03:把整个反射体系整理成 4 类知识地图——Class 类反射(成员属性/方法/构造)、Field 属性反射、Method 方法反射、Constructor 构造反射)+ Student 实体类(private/public/public static 字段设计 + 4 个构造方法 + 7 组 getter/setter + 私有方法 read/write)
 
 ---
 
@@ -22,9 +22,10 @@
 10. [获取 Method 对象的 4 个 API:Declared 与重载参数](#10-获取-method-对象的-4-个-apideclared-与重载参数)
 11. [Method 类的常用方法:invoke/setAccessible/getReturnType/getParameterTypes/getModifiers](#11-method-类的常用方法invokesetaccessiblegetreturntypegetparametertypesgetmodifiers)
 12. [Demo02 演示:遍历方法 + invoke 调用实例/带参/私有/静态方法](#12-demo02-演示遍历方法-invoke-调用实例带参私有静态方法)
-13. [知识点全景总结](#13-知识点全景总结)
-14. [随堂练习要点](#14-随堂练习要点)
-15. [拓展阅读](#15-拓展阅读)
+13. [反射知识全景总览(Demo03):四类反射的完整知识地图](#13-反射知识全景总览demo03四类反射的完整知识地图)
+14. [知识点全景总结](#14-知识点全景总结)
+15. [随堂练习要点](#15-随堂练习要点)
+16. [拓展阅读](#16-拓展阅读)
 
 ---
 
@@ -709,7 +710,87 @@ getSchool() 返回值=String
 
 ---
 
-## 13. 知识点全景总结
+## 13. 反射知识全景总览(Demo03):四类反射的完整知识地图
+
+### 概念 —— 把整个反射体系整理成 4 类知识地图
+
+学完了反射的三大核心成员(Constructor / Field / Method)+ 获取 Class 对象后,Demo03 用一段类注释把**整个反射知识体系整理成 4 类全景地图**——它是"反射到底有哪些 API"的**总索引**:先分清"针对哪一类做反射"(Class/Field/Method/Constructor),再记住"每一类反射关注什么、有哪些方法"。**Demo03 没有 main 方法,它就是一张纯知识点的知识地图**。
+
+```java
+// 来源:course/Demo03.java(类注释)
+/*
+    如果想要弄明白反射,需要掌握以下内容:
+        1、针对类的反射--Class-就需要记住类里面有哪些成员?
+            |- 成员属性
+                |- 获取一个对象:getField()
+                |- 获取多个对象(数组):getFields()
+                |- 获取一个私有对象:getDeclaredField()
+                |- 获取多个私有对象:getDeclaredFields()
+            |- 成员方法
+                |- 获取对象:getMethod()
+                |- 获取多个对象(数组):getMethods()
+                |- 获取一个私有对象:getDeclaredMethod()
+                |- 获取多个私有对象:getDeclaredMethods()
+            |- 构造方法
+                |- 获得对象:getConstructor()
+                |- 获取多个对象(数组):getConstructors()
+                |- 获取一个私有对象:getDeclaredConstructor()
+                |- 获取多个私有对象:getDeclaredConstructors()
+        2、针对属性的反射--Field-就需要记住属性的组成部分有哪些?
+            |- 属性变量名    getName()
+            |- 属性修饰符    getModifiers()
+            |- 属性值
+                |- 获取值 get()
+                |- 赋值  set()
+        3、针对方法的反射--Method-就需要记住方法的组成部分有哪些?
+            |- 方法名称     getName()
+            |- 执行方法     invoke()
+            |- 方法返回值类型  getReturnType()
+            |- 方法的参数列表类型    getParameterTypes()
+            |- 方法的修饰符     getModifiers()
+        4、针对构造放过的反射--Constructor--就需要记住构造方法的组成部分有哪些?
+            |- 构造方法的修饰符     getModifiers()
+            |- 构造方法的参数列表类型     getParameterTypes()
+            |- 创建对象     newInstance()
+*/
+```
+
+### 四类反射知识地图
+
+| 反射类别 | 关注点 | 获取对象的 API(4 个/类) | 对象自身的常用方法 |
+|----------|--------|--------------------------|---------------------|
+| **① Class 类反射** | 类里面有哪些**成员**(属性/方法/构造) | 属性:`getField`/`getFields`/`getDeclaredField`/`getDeclaredFields`;方法:`getMethod`/`getMethods`/`getDeclaredMethod`/`getDeclaredMethods`;构造:`getConstructor`/`getConstructors`/`getDeclaredConstructor`/`getDeclaredConstructors` | — |
+| **② Field 属性反射** | 属性的**组成部分**(名字/修饰符/值) | 获取方式见 Class 反射 | 属性名 `getName()`、修饰符 `getModifiers()`、**值 `get()` / `set()`** |
+| **③ Method 方法反射** | 方法的**组成部分**(名字/执行/返回值/参数/修饰符) | 获取方式见 Class 反射 | 方法名 `getName()`、**执行 `invoke()`**、返回值类型 `getReturnType()`、参数类型 `getParameterTypes()`、修饰符 `getModifiers()` |
+| **④ Constructor 构造反射** | 构造方法的**组成部分**(修饰符/参数/创建对象) | 获取方式见 Class 反射 | 修饰符 `getModifiers()`、参数类型 `getParameterTypes()`、**创建对象 `newInstance()`** |
+
+### 记忆要点:三组 12 个获取 API + 每类对象的关键方法
+
+**① 获取 API 的规律(3 组 × 4 个 = 12 个)**:每个成员(属性/方法/构造)都有**同样的 4 个获取方法**:
+
+| 成员 | 取多个(数组) | 取单个 | 取多个含私有 | 取单个含私有 |
+|------|---------------|--------|--------------|--------------|
+| 属性 | `getFields()` | `getField(name)` | `getDeclaredFields()` | `getDeclaredField(name)` |
+| 方法 | `getMethods()` | `getMethod(name, 参数类型...)` | `getDeclaredMethods()` | `getDeclaredMethod(name, 参数类型...)` |
+| 构造 | `getConstructors()` | `getConstructor(参数类型...)` | `getDeclaredConstructors()` | `getDeclaredConstructor(参数类型...)` |
+
+> **记忆口诀**:**含 `Declared` 的能拿私有(本类全部),不含 `Declared` 的只能拿 public(含父类/接口继承)**——三组获取 API 共用同一条口诀
+
+**② 每类反射对象的关键方法**:
+
+- **Field 看"属性值"**:属性有三部分——名字 `getName()`、修饰符 `getModifiers()`、**值 `get()` / `set()`**
+- **Method 看"执行"**:方法有五部分——名字 `getName()`、**执行 `invoke()`**、返回值类型 `getReturnType()`、参数类型 `getParameterTypes()`、修饰符 `getModifiers()`
+- **Constructor 看"创建"**:构造方法有三部分——修饰符 `getModifiers()`、参数类型 `getParameterTypes()`、**创建对象 `newInstance()`**
+- **三个反射对象共有的 API**:Field/Method/Constructor 都有 `getModifiers()`(返回 int,`Modifier.toString()` 解析)和 `getParameterTypes()`(Constructor/Method 有参数,Field 无参数)
+
+> **要点**:
+> - **反射的总纲**:先"拿 Class"→ 再"按成员类型拿反射对象"(Field/Method/Constructor)→ 最后"用反射对象操作成员"(get/set / invoke / newInstance)——Demo03 把这条路整理成了知识地图
+> - **12 个获取 API 有统一规律**:每个成员都是"4 个获取方法",只是前缀从 Field/Method/Constructor 换一下——记住一个就记住全部
+> - **本章"作业答案参考"**:练习五答案 `exericse/MethodPrintUtilTest.java`(遍历方法时用了 `setAccessible(true)` 暴力反射 + `Modifier.toString` + 字符串修复去掉方括号)、练习六答案 `exericse/MethodInvokeTest.java`(`invokeMethod` 通用工具用 `args[i].getClass()` **动态计算参数类型数组**)
+
+---
+
+## 14. 知识点全景总结
 
 | 知识点 | 核心内容 | 来源 |
 |--------|----------|------|
@@ -754,10 +835,18 @@ getSchool() 返回值=String
 | **演示:暴力反射私有方法** | `getDeclaredMethod("read")` + `setAccessible(true)` + `invoke(s)` 调用 private 实例方法;`getDeclaredMethod("write")` + `setAccessible(true)` + `invoke(null)` 调用 private 静态方法(传 null) | course/Demo02 main |
 | **反射三大成员统一套路** | Constructor(newInstance 创建对象)/ Field(get/set 读写字段)/ Method(invoke 调用方法)——**Declared 拿私有 + setAccessible(true) 放开权限**,操作静态成员(属性/方法)传 null | course/Demo01 + Demo02 |
 | **受检异常** | Demo01 main throws `ClassNotFoundException, NoSuchFieldException, IllegalAccessException`(Field);Demo02 main throws `NoSuchMethodException, InvocationTargetException, IllegalAccessException`(Method)——方法名/参数类型不匹配抛 NoSuchMethodException、被调方法内部抛异常时 invoke 抛 InvocationTargetException | course/Demo01 + Demo02 main |
+| **反射知识全景总览(Demo03)** | 把整个反射体系整理成 4 类知识地图:①Class 类反射(类里的成员——属性/方法/构造)②Field 属性反射(属性的组成部分)③Method 方法反射(方法的组成部分)④Constructor 构造反射(构造方法的组成部分)——Demo03 没有 main 方法,是纯知识点类 | course/Demo03 注释 |
+| **12 个获取 API 的统一规律** | 属性/方法/构造各有 4 个获取方法(数组/单个/含私有数组/含私有单个)——`getXxx(s)` / `getDeclaredXxx(s)`,口诀"含 Declared 的能拿私有"统一适用于三组 | course/Demo03 注释 |
+| **Field 属性三部分组成** | 属性变量名 `getName()` / 属性修饰符 `getModifiers()` / 属性值 `get()` + `set()` | course/Demo03 注释 |
+| **Method 方法五部分组成** | 方法名称 `getName()` / 执行方法 `invoke()` / 返回值类型 `getReturnType()` / 参数列表类型 `getParameterTypes()` / 修饰符 `getModifiers()` | course/Demo03 注释 |
+| **Constructor 构造三部分组成** | 构造方法修饰符 `getModifiers()` / 参数列表类型 `getParameterTypes()` / 创建对象 `newInstance()` | course/Demo03 注释 |
+| **练习五答案参考** | `exericse/MethodPrintUtilTest.java`——printDeclaredMethods 遍历时用 `setAccessible(true)` 暴力反射 + `Modifier.toString` 解析修饰符 + **字符串修复**(replace 去掉参数类型 List 的 `[` `]` 方括号) | exericse/MethodPrintUtilTest.java |
+| **练习六答案参考** | `exericse/MethodInvokeTest.java`——invokeMethod 通用工具用 **`args[i].getClass()` 动态计算参数类型数组**(不写死参数类型),再 `getMethod(methodName, classes)` + `invoke(obj, args)`;无参数与有参数两种分支处理 | exericse/MethodInvokeTest.java |
+| **exericse/Student 实体类** | 练习包 `exericse` 的实体类:private(id/name/age)+ public static(school)+ 新增 getter/setter + `eat(String s)` 方法(打印"吃:s")——练习五/六的反射目标 | exericse/Student.java |
 
 ---
 
-## 14. 随堂练习要点
+## 15. 随堂练习要点
 
 - **Field 概念复述(必做)**:用一句话说清"什么是 Field 反射"——Field 对象代表类中的一个成员变量,反射通过 `get()` 读取字段值、`set()` 修改字段值;能说出框架中的应用(ORM 框架查询数据库后用 Field.set() 把数据映射到 Java 类)
 - **获取 Field 的 4 个 API 背诵(必做)**:`getFields()`(所有 public 数组,含父类继承)/ `getField(String name)`(指定 public)/ `getDeclaredFields()`(本类全部含 private,不含父类)/ `getDeclaredField(String name)`(指定含 private)——背口诀:**含 Declared 的能拿私有(本类全部),不含 Declared 的只能拿 public(含父类继承)**
@@ -786,10 +875,17 @@ getSchool() 返回值=String
 - **getMethods vs getDeclaredMethods 对比**:思考两者的区别——getMethods 拿 public + 父类/接口继承;getDeclaredMethods 拿本类全部(含 private)不含父类。数一数 Student 的 getMethods() 输出里有哪些是 Object 继承来的(toString/hashCode/equals/getClass/notify/wait 等)
 - **InvocationTargetException 理解**:把 `read()` 方法体内故意写一个会抛异常的语句(如 `int x = 1/0`),反射 `invoke` 调用它,观察抛 **InvocationTargetException**(被调方法内部异常被包装)——回顾 07-28 异常处理知识
 - **练习答案参考**:课堂练习四(模拟 ORM mapToObject)的参考答案代码在 `exericse/OrmFieldMapTest.java`(含 `exericse/Student.java` 实体类)——运行观察静态字段传 null 操作 + Map 数据库行映射到 Student 对象的完整流程
+- **反射知识全景背诵(必做)**:把 Demo03 的 4 类知识地图背下来——①Class 类反射(成员属性/方法/构造)②Field 属性反射(名字/修饰符/值)③Method 方法反射(名字/执行/返回值/参数/修饰符)④Constructor 构造反射(修饰符/参数/创建对象)——能不看笔记默写出来
+- **12 个获取 API 默写(必做)**:给"属性/方法/构造"各自默写 4 个获取方法(数组/单个/含私有数组/含私有单个)——`getFields`/`getField`/`getDeclaredFields`/`getDeclaredField`(属性)、`getMethods`/`getMethod`/`getDeclaredMethods`/`getDeclaredMethod`(方法)、`getConstructors`/`getConstructor`/`getDeclaredConstructors`/`getDeclaredConstructor`(构造)——体会"三组 12 个 API 规律完全一致"
+- **口诀统一性验证**:对照 12 个获取 API,逐个确认"含 Declared 的能拿私有、不含 Declared 的只能拿 public"对属性/方法/构造三组都成立——这是反射 API 的统一规律
+- **反射对象共有 API 对比(必做)**:列出 Field/Method/Constructor 三者**共同有的方法**(`getModifiers()` 修饰符 + `getName()`),以及各自**独有的方法**(Field:get/set;Method:invoke/getReturnType/getParameterTypes;Constructor:newInstance/getParameterTypes)——画一张对比表
+- **练习五答案参考**:`exericse/MethodPrintUtilTest.java`——printDeclaredMethods 遍历时对每个方法 `setAccessible(true)` + `Modifier.toString` 解析修饰符 + 字符串修复(replace 去掉参数类型 List 的 `[` `]`);运行观察输出 `private void write()` 这类带修饰符的方法行
+- **练习六答案参考**:`exericse/MethodInvokeTest.java`——`invokeMethod` 通用工具用 `args[i].getClass()` **动态计算参数类型数组**(不需要写死 String.class),并区分"有参数/无参数"两个分支;main 里调用 `invokeMethod(s, "eat", "饭...")` 调用 exericse/Student 新增的 `eat(String)` 方法
+- **Demo03 无 main 方法理解**:观察 Demo03 类只有大段注释没有 main 方法——体会"注释也能承载知识点":反射知识地图以注释形式存在,需要时打开 Demo03.java 即可总览全部反射 API
 
 ---
 
-## 15. 拓展阅读
+## 16. 拓展阅读
 
 - **反射 Field 在 ORM 框架中的落地**:MyBatis、Hibernate 等 ORM 框架的**结果映射(Result Mapping)**就是本课"Field.set() 把数据库数据映射到 Java 类"的经典实现——数据库表字段名对应 Java 实体属性名,查询结果通过反射 Field.set() 逐字段赋值
 - **反射三大核心成员(已全部学完)**:反射三大核心成员已全部掌握——**Constructor(构造方法,08-12 newInstance 创建对象)+ Field(字段属性,本课 get/set 读写字段)+ Method(方法,本课 invoke 调用方法)**——三者套路完全一致:`getDeclaredXxx` 拿私有 + `setAccessible(true)` 放开权限 + 执行操作;至此反射三件套(建对象/读写属性/调方法)可组合完成框架级操作
@@ -809,5 +905,9 @@ getSchool() 返回值=String
 - **IDEA 调试器的实现原理**:IDEA 等 IDE 的**调试器变量查看窗口**能在运行时显示对象的所有字段值(包括 private)——底层就是反射 `getDeclaredFields()` + `setAccessible(true)` + `field.get(对象)`,与本课 Demo01 的演示逻辑一致
 - **JSON 序列化框架**:Jackson / Gson / Fastjson 把 Java 对象转成 JSON 字符串、或把 JSON 转回对象,底层也大量使用 Field 反射——读取对象所有字段名与值(序列化)、按 JSON 键名给对象字段赋值(反序列化)
 - **反射破坏封装性的辩证关系**:本课 Field 反射可以访问 private 字段、修改 final 字段,既是框架能力的来源,也是"破坏封装性"的体现——日常业务代码中应遵守上一课的原则:**正常业务用普通方式访问属性,反射留给框架与中间件**
-- **JDK 文档**:[`java.lang.Class`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Class.html)(getFields/getField/getDeclaredFields/getDeclaredField + getMethods/getMethod/getDeclaredMethods/getDeclaredMethod)、[`java.lang.reflect.Field`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Field.html)(get/set/setAccessible/getType/getName/getModifiers)、[`java.lang.reflect.Method`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Method.html)(invoke/setAccessible/getReturnType/getParameterTypes/getModifiers)、[`java.lang.reflect.Modifier`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Modifier.html)(toString/isPublic/isStatic 等修饰符解析工具类)
+- **反射 API 的"总索引"价值**:Demo03 的类注释相当于一张**反射 API 速查表**——面试或写框架代码时"忘了某个 API 名字",打开 Demo03.java 就能看到 4 类反射的全部方法(Class 的 12 个获取方法 + Field/Method/Constructor 各自的组成部分方法);这种"用注释承载知识地图"的做法也适合自己整理学习笔记
+- **12 个获取 API 与"组合拳"思维**:反射 3 个成员(Field/Method/Constructor)× 4 种获取方式(数组/单个/含私有数组/含私有单个)= 12 个 API,规律完全一致——记住"每个成员 4 个获取方法 + Declared 口诀"就能举一反三,这也是面试常考的"反射 API 全家桶"
+- **Constructor 反射的补充方法**:Demo03 提到 Constructor 也有 `getModifiers()`(构造修饰符)和 `getParameterTypes()`(构造参数类型)——上一课(08-12)主要用了 `newInstance()` 创建对象,这两个方法是构造反射的补充维度,可在练习中试用(打印构造方法的修饰符与参数类型)
+- **练习答案中的通用工具设计**:练习五答案用"遍历 + setAccessible + Modifier.toString + 字符串修复"打印方法信息、练习六答案用"`args[i].getClass()` 动态计算参数类型"实现通用 invoke——这两种技巧(字符串清理、动态参数类型推导)是写反射通用工具的常用套路,后续做框架级工具时可直接复用
+- **JDK 文档**:[`java.lang.Class`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Class.html)(getFields/getField/getDeclaredFields/getDeclaredField + getMethods/getMethod/getDeclaredMethods/getDeclaredMethod + getConstructors/getConstructor/getDeclaredConstructors/getDeclaredConstructor)、[`java.lang.reflect.Field`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Field.html)(get/set/setAccessible/getType/getName/getModifiers)、[`java.lang.reflect.Method`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Method.html)(invoke/setAccessible/getReturnType/getParameterTypes/getModifiers)、[`java.lang.reflect.Constructor`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Constructor.html)(newInstance/setAccessible/getModifiers/getParameterTypes)、[`java.lang.reflect.Modifier`](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/Modifier.html)(toString/isPublic/isStatic 等修饰符解析工具类)
 

Некоторые файлы не были показаны из-за большого количества измененных файлов