《Java 100 天进阶之路》第28篇:Java反射机制原理详解
第28篇Java反射机制原理详解系列导航《Java 100 天进阶之路》完整目录 |⬅️ 上一篇第27篇Java代理类详解 |➡️ 下一篇第29篇Java Date类详解待发布一、核心知识点反射的核心能力运行时获取类信息、创建对象、调用方法、访问字段包括私有获得Class对象的三种方式Class.forName()、对象.getClass()、类名.class核心 APIClass、Method、Field、Constructor反射的优缺点灵活、动态 vs 性能开销、破坏封装、安全隐患反射的应用框架Spring、MyBatis、注解处理、动态代理、序列化二、通俗讲解1分钟开心学1. 什么是反射反射就是在程序运行时动态地获取类的信息有哪些方法、字段、构造器并且可以调用它们甚至访问私有成员。就好像你在黑暗中用手电筒照一个物体能看清它的所有细节。2. 获得 Class 对象的三种方式Class.forName(全限定类名)最常用会触发类初始化。对象.getClass()已经有实例时使用。类名.class编译时已知类型最直接不触发初始化。3. 反射能做什么创建实例替代new调用方法包括私有方法读写字段包括私有字段获取注解信息获取泛型类型信息4. 反射的代价性能比直接调用稍差但现代 JVM 有优化破坏封装性可能绕过权限检查代码可读性下降容易出错生活类比正常编程就像拿着说明书组装家具编译时已知。反射就像你拿到一个没拆封的快递运行时才知道里面是什么你得用工具把它拆开看清里面所有零件再组装。三、实操代码案例 场景说明场景写一个通用的toString工具可以打印任意对象的字段值。importjava.lang.reflect.Field;importjava.lang.reflect.Method;publicclassReflectionDemo{publicstaticvoidmain(String[]args)throwsException{// 1. 获取Class对象的三种方式Class?clazz1Class.forName(java.lang.String);Class?clazz2hello.getClass();Class?clazz3String.class;System.out.println(clazz1clazz2);// true// 2. 创建对象调用无参构造Class?personClazzPerson.class;Personp(Person)personClazz.getDeclaredConstructor().newInstance();p.setName(张三);// 3. 调用私有方法MethodprivateMethodpersonClazz.getDeclaredMethod(secret,String.class);privateMethod.setAccessible(true);// 绕过访问检查privateMethod.invoke(p,密码123);// 4. 修改私有字段FieldnameFieldpersonClazz.getDeclaredField(name);nameField.setAccessible(true);nameField.set(p,李四);System.out.println(p.getName());// 李四// 5. 遍历所有字段通用toStringSystem.out.println(objectToString(p));}// 通用toString打印对象所有字段名和值publicstaticStringobjectToString(Objectobj)throwsIllegalAccessException{StringBuildersbnewStringBuilder();Class?clazzobj.getClass();sb.append(clazz.getSimpleName()).append({);Field[]fieldsclazz.getDeclaredFields();for(inti0;ifields.length;i){fields[i].setAccessible(true);sb.append(fields[i].getName()).append().append(fields[i].get(obj));if(ifields.length-1)sb.append(, );}sb.append(});returnsb.toString();}}classPerson{privateStringname;publicvoidsetName(Stringname){this.namename;}publicStringgetName(){returnname;}privatevoidsecret(Stringkey){System.out.println(私有方法被调用keykey);}}四、避坑要点错误/误区后果正确做法频繁调用反射如循环中性能下降缓存Method或Field对象忘记setAccessible(true)IllegalAccessException访问私有成员前必须设置Class.forName()与ClassLoader.loadClass()混淆前者会初始化静态块后者不会根据需求选择反射调用方法参数类型不匹配IllegalArgumentException确保参数类型完全匹配包括基本类型 vs 包装类五、面试高频考点Q1反射的优缺点优点动态性框架基础提高代码灵活性。缺点性能略低破坏封装存在安全隐患可访问私有数据。Q2getMethod和getDeclaredMethod的区别getMethod获取 public 方法包括继承的getDeclaredMethod获取本类声明的所有访问级别的方法不包括继承。Q3反射可以获取泛型参数化类型信息吗可以。通过Method.getGenericParameterTypes()等获取Type对象可得到实际类型参数如果编译时保留了泛型信息。六、练习题动手写一个方法接收一个对象打印该对象的所有方法名称包括私有。代码分析利用反射创建ArrayListInteger实例并添加元素再通过反射遍历输出。简答Spring 框架中哪些地方使用了反射 你的学习进度当前第28篇 / 共44篇 ·第四阶段注解、反射、代理、日期第26~31篇✅ 已完成第1~27篇 正在学第28篇⏳ 待学习第29~44篇 完整目录 学习指南 | 订阅本专栏不错过每一篇 本专栏每篇都包含避坑表 面试高频考点 练习题。每天30分钟100天拿offer下一篇文章预告《Java Date 类详解》内容简介Date类的缺陷、SimpleDateFormat线程不安全、java.time包LocalDate/LocalDateTime/DateTimeFormatter。 学完这篇你将彻底告别旧版日期API的坑写出线程安全的日期处理代码。《Java 100 天进阶之路 | 从入门到上岗就业》每天一篇建议收藏 关注一起100天拿offer 点击关注我更新后第一时间收到推送