
文章目录482. Java 反射 - 访问私有方法 泛型擦除的影响1. 访问私有方法 (Accessing Private Methods)直接调用的问题解决办法setAccessible(true)输出结果2. 泛型与类型擦除 (Generics and Type Erasure)错误示例正确示例3. 总结482. Java 反射 - 访问私有方法 泛型擦除的影响1. 访问私有方法 (Accessing Private Methods)直接调用的问题如果你在类外部通过反射尝试调用一个private 方法会抛出IllegalAccessException。classUser{privatevoidsecret(){System.out.println(Top Secret!);}}User user new User(); Method secretMethod User.class.getDeclaredMethod(secret); secretMethod.invoke(user); // ❌ 会抛 IllegalAccessException解决办法setAccessible(true)我们可以通过关闭访问检查来绕过限制secretMethod.setAccessible(true);// 关闭 Java 语言访问检查secretMethod.invoke(user);// ✅ 正常执行输出结果TopSecret!注意点setAccessible(true)只是关闭了访问控制检查它不会改变方法的修饰符。在Java 模块系统Java 9下如果类属于其他模块且模块没有开放包调用可能依然会失败需要--add-opens。2. 泛型与类型擦除 (Generics and Type Erasure)在 Java 中泛型是编译期特性运行时会发生类型擦除。这意味着反射看到的其实是擦除后的类型而不是源代码中的泛型。错误示例ListStringstringsnewArrayList();Class?clazzstrings.getClass();// ❌ 尝试获取 add(String) 方法MethodaddStringclazz.getMethod(add,String.class);运行结果Exceptionin threadmainjava.lang.NoSuchMethodException:java.util.ArrayList.add(java.lang.String)原因ArrayListE.add(E e)在运行时擦除为ArrayList.add(Object o)所以找不到参数是String.class的方法正确示例ListStringstringsnewArrayList();Class?clazzstrings.getClass();// ✅ 使用 Object.class 才能找到 add()MethodaddObjectclazz.getMethod(add,Object.class);addObject.invoke(strings,Hello Reflection!);System.out.println(strings);输出结果[HelloReflection!]注意点反射操作是基于擦除后的类型因此需要用Object.class。这样会失去泛型带来的类型安全你甚至可以通过反射往ListString里塞一个Integer。3. 总结✅私有方法默认不可访问 → 需要setAccessible(true)在模块化环境中可能需要--add-opens✅泛型与擦除编译期有泛型运行期被擦除反射看到的参数类型通常是Object使用反射会丢失泛型检查可能破坏类型安全