动态代理的内存分析
本文章是作者用于记忆学习的,水平有限,如有错误,希望指点。
- 代码
- 分析
- 内存图
代码
-
public interface ISingStar{
- public void sing(int price){};
- public void dance(int price){};
-
public void eat(int price){};
}
public class TaiwanStar implemets ISingStar{
- private String name;
- @override
- public void dance(int price){
- System.out.println(name+”正在跳舞!”);
- @override
- public void sing(int price){
- System.out.println(name+”正在唱歌!”);
- public String getName(){
- return name;
- }
- public void setName(){
- super();
- this.name=name;
- }
- public TaiwanStart(String name)
- super();
- this.name=name;
- }
- public TaiwanStar(){
- } } public class StarInvocation implements InvocationHandler{
- private ISingStar star;
- public StartInvocation(ISingStar star){
- super();
- this.star=star;
- }
- @override
- public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
- System.out.println(“StarInvocation.invoke():真正的歌星唱歌前!”);
- int p=(Integer)args[0];
- if(p>10000){
- return method.invoke(star,args);
- }else{
- System.out.println(“钱太少!”);
- return null;
- } } } public class Test{
- public static void main(String [] args){
- ISingStar s1=new TaiwanStar(“周杰伦”);
- StarInvocation sh=new StarInvocation(s1);
- ISingStar pro=(ISingStar)Proxy.newProxyInstance(Test.class.getClassLoader(),new Class[]{ISingStar.class},sh);
- pro.dance(3000);
- }
}
分析
进入test.main(),首先方法区和堆中创建相关信息,在栈中创建引用,关系如下图所示,sh对象是处理真是的SingStar和代理类 pro之间的逻辑关系的类,创建pro代理类时,(ISingStar)Proxy.newProxyInstance(Test.class.getClassLoader(),new Class[]{ISingStar.class},sh),第一个参数是类加载器对象(由类加载器创建),加载器的作用是从硬盘把.class对象加载到内存中去。第二个参数,就是要构建的假的class对象。第三个参数是将sh引用放到pro代理对象中去。当调用pro.dance(3000)时,其实是调用了sh.invoke()方法。