1.反射的思想以及作用
学习反射之前,先了解正射。**正射:通过new关键字来实例化对象。**假如我们需要实例化一个HashMap对象,代码如下:
某一天发现程序不适合用HashMap存储,更适合用LinkedHashMap存储,然后重新编写代码如下:
如果又有一天,我们发现数据还是更适合用HashMap来存储,可能又需要修改源代码。使用正射存在的问题就是当需求变更的时候,都需要重新修改源码,然后对代码进行编译,打包,到JVM上重启项目,导致效率十分低下。
当需求变更频繁但是变更不大的时候,我们可以使用一个开关,也就是通过传入参数来决定用哪一种数据结构。
但是一旦需求的变更比较大,这种方式也难以胜任,这个时候就需要用到反射。
反射:在代码运行之前不确定使用哪一种数据结构,在程序运行时才决定,在程序运行过程中动态获取类信息和调用类方法。
通过反射实例化map:
小结:
(1).反射的思想:在程序运行过程中确定和解析数据类的类型。
(2).反射的作用:对于编译期无法确定使用哪个数据类的场景,可以通过反射在程序运行时构造出不同的数据类实例。
2.反射的基本使用
2.1主要组成部分有4个:
(1).Class类。运行在内存中的所有类都是该类的实例对象,每个Class对象都包括本类的所有信息。
(2).Field类。描述类的属性,包含属性的所有属性,如数据类型,属性名,访问修饰符.......
(3).Constructor类。描述类的构造方法。
(4).Method类。描述类除构造方法之外的所有方法。
2.2反射的主要功能:
(1)在运行时获取一个类的Class对象。
(2)在运行时获取一个类的实例对象。
(3)在运行时获取一个类的所有信息,属性,方法,构造器和注解等。
2.3获取Class对象的三种方式:
(1).类名.class
(2).实例对象.getClass()
(3).Class.forName(className) className类的全类名路径
2.4获取实例对象的两种方式:
(1)class对象调用newInstance()方法。
(2)class对象获取构造器Construtor,然后构造器调用newInstance()方法。
区别:通过Class对象调用newInstance()方法构造实例调用的是默认无参构造方法,如果想通过显示构造方法构造实例使用第二种。
3.反射的应用场景举例
JDBC加载数据库驱动类
在导入第三方库时,JVM不会主动去加载外部导入的类,而是等到真正使用时,才去加载需要的类,正是如此,我们可以在获取数据库连接时传入驱动类的全类名,交给 JVM 加载该类。
4.反射的优缺点:
反射的优点:
增加程序的灵活性:面对需求变更时,可以灵活地实例化不同对象
但是,有得必有失,一项技术不可能只有优点没有缺点,反射也有两个比较隐晦的缺点:
破坏类的封装性:可以强制访问 private 修饰的信息
性能损耗:反射相比直接实例化对象、调用方法、访问变量,中间需要非常多的检查步骤和解析步骤,JVM无法对它们优化。