关于 JAVA 反射机制
目录
关于 JAVA 反射机制
0.1 背景
关于 JAVA 的反射机制,之前学的有点混:
- 动态创建类、动态调用方法,这部分还比较好理解
- 但关于 “编译依赖”、“运行依赖” 这部分,就有点云里雾里
最近在学框架,再次遇到这个问题,百思不得其解:
为什么 “编译依赖” 这么不受待见,问题不是越早发现越好吗?编译器报错,甚至 IDE 环境提前提示错误,难道不比等到运行的时候再发现错误更好?
于是一番查询检索,但绝大多数资料,都只是抄书似的介绍一下各个 API 的使用,真是毫无意义、却无比浪费时间的一锅信息粥。
最后想着试试找个课程翻翻看,在慕课网的这个专题课程1找到了解答
0.2 关于 “编译依赖”、“运行依赖”
这其实是关于解耦合的概念,属于软件工程的范畴。
在进行项目开发的时候,功能拆分、模块化设计,可以使整个程序结构更有条理,有利于分工合作,有利于代码复用,有利于维护拓展,从而在多个方面提高效率。低耦合的设计,是重要,且非常必要的设计思想。
但如果只是简单地把功能拆分,各功能、模块,各个类之间还是直接地调用、直接地创建对象,那么,在某个位置发生代码改变的时候,牵一发而动全身,实际上可能需要修改大量其他各处的相关代码。这样的情况,属于 “编译依赖”。
而如果能实现:各个功能、模块、类内部修改代码,不会影响到其他功能、模块、类,这样才真正实现了模块化,可称为 “运行依赖”。
用这个课程中老师举的例子来说:
- 现在有一个 Web 项目,有一个接口 “A” ,有多个实现类(A1, A2 …)交给不同的工程师开发,另外有一个 “B” 类,调用其中不同的实现类来实现不一样的功能。
- “B”、“A”、“A1”,都已完成开发,“A2” 还没完成。
- 如果处于 “编译依赖” 的情形,那么,只能等 “A2” 完成开发,再进行测试,或者注释掉 “B” 类中关于 “A2” 的相关代码,进行测试。
- 如果达到了 “运行依赖” 的情形,则可以直接进行测试,只要不使用 “A2” 的链接、按钮就可以。
孰优孰劣,一目了然。这段内容,对 本X 而言,可称得上是 “醍醐灌顶”。听老师一席话,胜喝互联网十锅粥。
所以,反射机制非常重要。
0.3 关于 “泛型”
其次,关于 “泛型” ,我们知道 “泛型只在编译阶段有效,而实际运行时,是不区分对象类型的” ,这其实也可以通过反射来证实:
|
|
测试中可以明显看到:
- 直接向 String 泛型的 List 添加数值类型的 20 ,IDE 会提示,编译过程也会报错;
- 但如果使用反射,可以绕过编译阶段的泛型检查,顺利编译运行。
- 证实了 “泛型只在编译阶段有效,而实际运行时,是不区分对象类型的”
此时,如果使用 String 类型来进行 for each 遍历,顺利编译,但运行报错:
|
|
若使用 Object 类型,则能够正常遍历出来:
|
|