一、 反射
反射是在程序运行状态下,动态获取类的结构(属性,构造器,方法,注解),动态的创建类对象然后调用类中的属性方法。反射的起源Class,Class中包含类反射要使用的API
获取Class的方法
public class Student{
private Integer sId;
private String sName;
private Integer getsId() {
return sId;
}
private void setsId(Integer sId) {
this.sId = sId;
}
private String getsName() {
return sName;
}
private void setsName(String sName) {
this.sName = sName;
}
public Student(Integer sId, String sName) {
this.sId = sId;
this.sName = sName;
}
}
反射的方法:
0) 获取类类型 对象
Class<Student> stu = Student.class
0.5)获取类 对象
Student stuObj = stu.new Instance() //默认获取无参构造方法
等价于
Student stuObj = stu.getConstructor().new Instance()
1)获取属性
Field sName = stu.getDeclaredField(''sName'')
sName.setAccessible(true)
Field sId = stu.getDeclaredField("sId")
sId.setAccessible(true)
属性设置值
sName.set(stuObj,''张三'')
sId.set(stuObj,1)
2)获取方法
Method getsId = stu.getMethod("getsId")
getsId.invoke(stuObj)
3) 获取构造方法
Constructor c = stu.getConstructor(Integer.class,String.class)
Student s = c.new Instance(1,"张三")
注意事项:
反射获取方法,构造方法,属性方法中 方法名都有加Declared 与 不加Declared。
不加Declared:能够获取父子类中所有public修饰的方法
追加Declared:能够获取当前类中所有修饰符的方法
二)类加载
方法区:放置读取的.class文件
堆区:放置class文件生成的class对象
类加载的过程:
1)转载:查找并加载class文件
2)链接:
验证:验证字节码文件是否符合JVM规范。
准备:为类的静态变量分配内存,初始化化默认值
解析:类中的符号引用转换为直接引用
3)初始化:为类的静态变量赋予正确的初始值
三)Proxy 静态代理和jdk的动态代理
Spring 框架:
IOC控制反转:把项目javabean对象的创建以继生命周期交给spring框架管理
需要使用bean对象时,直接从Spring容器(bean对象的容器)中获取。
利用java的反射,实例化bean对象
AOP面向切面编程:两种动态代理实现
jdk动态代理:实现接口
cglib动态代理:单独的类,没有实现接口
在不修改源代码的情况下扩展功能
静态代理:
目标对象:执行类中方法
代理对象:代理对象中包含目标对象,调用执行对象时可以额外添加功能
注意:静态代理是提前写死的.class文件,并且两个对象类实现同一个接口。跟接口耦合性太高,改动麻烦。
动态代理:
jdk动态代理:
cglib代理: