反射机制与动态代理
以前学习基础的时候不知道哪些是重点,也不会注意,自己动手少,用的少,自然也不会知道,就落下了知识点,当被问反射机制起来时,听过,但怎么说,到底是怎么一回事,脑子一片空白,答不上来,也觉得惭愧。
一.什么是反射机制?
在运行期中,对于任意一个类,都能够调用某一个类的属性与方法,或者对与一个对象,任意的对象都能调用这个对象的属性和方法,这个类或对象相对其他类或对象像是透明的。这种动态的调用其他类或者对象的属性和方法就叫做反射机制,JAVA反射机制:”程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言“,这样说你可能会感觉模模糊糊的,不太懂。
反射机制通过或者某个类或对象的字节码文件对象(.class),这是必须的,通过字节码对象就能获取该类的属性和方法,
获取字节码文件对象的三种方式,针对不同情况下选择合理的使用
1、
源码阶段,并没有变成字节码文件
//创建源码期的字节码文件对象,参数为类的路径即包名+类名,相对路径即类名
Class a = Class.forName("A");
//创建实例对象
A a1 = (A)a.newInstance();
2、
编译期后字节码阶段
//创建编译期的字节码文件对象
Class a = A.class;
3、
创建对象阶段
//创建对象
A as = new A();
//创建对象期的字节码文件对象
Class a = as.getClass();
通过反射机制过去的字节码文件对象能干嘛?
假设已存在A类
1.创建实际对象
//创建编译期的字节码文件对象
Class a = A.class;
//创建实例对象
A a1 = (A)a.newInstance();
2.获取该类的构造器
//创建编译期的字节码文件对象
Class a = A.class;
//通过字节码对象获取无参构造器,通过构造器创建实例对象
Constructor constructor = a.getConstructor();
A a2 =(A)constructor.newInstance();
//带参构造器
Constructor constructor1 = a.getConstructor(String.class);
System.out.println("初始化带参构造器");
A a3 = (A)constructor1.newInstance("削功名");
3.获取该类的属性并输出
//创建实例对象
Class a = A.class;
A a1 = (A)a.newInstance();
//调用该类的属性,形参传入属性名
Field field = a.getDeclaredField("name");
//及那个私有的属性打开权限
field.setAccessible(true);
//get方法参数传入该类的实例对象
System.out.println(field.get(a1));
4.获取该类的方法并执行
//创建编译期的字节码文件对象
Class a = A.class;
//创建实例对象
A a1 = (A)a.newInstance();
//调用该类方法(参数为该类的方法名)
Method method = a.getMethod("hello");
//参数传入一个实例参数
method.invoke(a1);
二.动态代理
1.什么是动态代理?
动态代理是一种设计模式,可以这么理解,比如自己需要买一瓶水,自己不想动,叫人帮买一瓶水。这个代理对象是在程序运行过程中创建的,这个我们反射机制一样在程序运行过程中来实例化对象、调用方法等操作。
创建代理对象需要使用 ava.lang.reflect下的 Proxy 类 和 InvocationHandler 接口; JDK提供的代理只能针对接口做代理,这意味着我们返回的必须是一个接口对象。更强的代理通过Proxy的newProxyInstance()方法创建动态代理对象。
1、创建一个接口,在接口中写个方法
public interface A {
void buy();
}
2.创建一个InvocationHandle 代理对象
public class B implements InvocationHandler {
private Object target;
public B(Object a){
this.target = a;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
method.invoke(target,args);
System.out.print("代理对象: 某某");
return null;
}
}
3.创建一个实例类,并通过代理执行
public class C implements A {
@Override
public void buy() {
System.out.println("买水");
}
public static void main(String[] args) {
C a = new C() ;
//本身来做
a.buy();
System.out.println("----------------");
//传入一个实例对象
B b = new B(a);
/**
* JDK提供的接口只能针对接口做代理。因此返回必须是个接口
* 参数为 实例对象的类加载器,类实现的所有接口的对象,代理对象
*/
A aa = (A)Proxy.newProxyInstance(a.getClass().getClassLoader(),a.getClass().getInterfaces(),b);
//代理来做
aa.buy();
}
}
还没有评论,来说两句吧...