为什么需要原理?
1、满足框架的需要,通过外部配置文件,在不朽还源码的情况下控制程序,符合设计模式的ocp原则(开闭原则:在不修改源码的情况下,开扩展功能【对修改封闭,对扩展开放】)
2、可以动态的加载一些之前用不到的类到JVM,最大程度体现JVM的灵活性(多态)
什么是反射?
反射机制允许程序在执行期间借助Reflection API取得任何类的内部信息,并能够操作对象的属性和方法,在设计模式和框架底层都会用到
简单来说,JVM需要动态的加载类,而在加载后堆中会产生一个类对象(注意不是类的实例对象),类对象只有一个,存储类的完整结构信息,就像一面镜子,反射就是通过这面镜子得到类的完整结构
Java程序计算机三个阶段:
编译阶段:,java文件成为.class文件
加载阶段:生成class对象
运行阶段:生成实例对象,运行实例对象的方法
也就是说,加载的时候会创建镜子,使用反射机制就是通过镜子找到类的结构信息
出自韩顺平
反射能够做什么?
1、运行时判断任意一个对象所属的类
2、运行时构造任意一个类的对象
3、运行时得到任意一个类所具有的成员变量和方法
4、运行时调用任意一个对象的成员变量和方法
5、生成动态代理
反射的相关类:
java.lang.Class:代表一个类,Class对象标识某个类加载后在堆中的对象
java.lang.reflect.Method:代表类的方法,Method对象标识某个类的方法
java.lang.reflect.Field:代表类的成员变量,Field对象标识某个类的成员变量
java.lang.reflect.Constructor:代表类的构造方法,Constructor对象表示构造器
反射的优点和缺点:
优点:可以动态的创建和使用对象(框架的核心),使用灵活,没有反射机制框架技术会失去底层支持
例如:定义了一个接口,实现这个接口的类有20个,程序里用到了相关实现类的地方有好多,如果不使用配置文件手写的话,代码的改动量很大,因为每个地方都要改而且不容易定位,如果你在编写之前先将接口与实现类的写在配置文件里,下次只需改配置文件,利用反射(java API已经封装好了,直接用就可以用 Class.newInstance())就可完成
缺点:
反射机制是解释执行,随用随加载,对执行速度有影响。
反射等绕过了源代码的技术,因而会带来维护问题,反射代码比相应的直接代码更复杂。
反射访问私有成员需要解除安全限制,程序运行在一个没有安全限制的环境中本身就是一个问题
Class类:
1、继承与Object类
2、类对象不是new出来的,而是系统创建的
3、某个类的类对象,内存中只有一个,在类加载的时候产生,类只加载以此
4、每个类的实例都会记得自己是由哪个Class对象所产生
5、通过Class对象可以得到一个类的完整结构
6、Class对象存放在堆中
7、类的字节码二进制数据放在方法区,有的地方成为类的元数据(包括方法代码,变量名,方法名,访问权限)
静态加载:编译时加载相关的类,如果没有则报错,依赖性强
动态加载:运行时加载需要的类,如果运行时不用该类,即使不存在该类也不报错,降低了依赖性
类加载时机:
1、创建对象(new)
2、子类被加载时,子类加载时会先调用父类加载
3、调用类中静态成员
4、通过反射
出自韩顺平
加载和连接由JVM负责,初始化(写的静态代码块等)由程序员控制
验证:文件格式,元数据,字节码,符号引用
准备:对静态变量分配内存,默认初始化
解析:将符号引用换为直接引用,在编译阶段A类引用B类,此时由于还没有加载入内存,没有真正的地址,只能用一个没有歧义能够确定无疑定位到B类的符号来代替,载入内存后会给.class文件分配内存,此时将对应的符号换为实际的地址
初始化:执行Java的代码【静态变量的赋值动作,静态代码块】
在反射中,如果方法有返回值,同意返回为Object,运行类型和和方法定义的类型保持一致