张孝祥高薪技术7(JVM动态生成的类.

  ----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

1  分析JVM动态生成的类
   创建实现了Collection接口的动态类和查看其名称,分析Proxy.getProxyClass方法的各个参数。
编码列出动态类中的所有构造方法和参数签名
编码列出动态类中的所有方法和参数签名
创建动态类的实例对象
用反射获得构造方法
编写一个最简单的InvocationHandler类
调用构造方法创建动态类的实例对象,并将编写的InvocationHandler类的实例对象传进去
打印创建的对象和调用对象的没有返回值的方法和getClass方法,演示调用其他有返回值的方法报告了异常。
将创建动态类的实例对象的代理改成匿名内部类的形式编写,锻炼大家习惯匿名内部类。
    用下面的代码可以吗?
 clazz.newInstance() ;
 clazz.getConstructor().newInstance();
    答:不可以,newInstance()用的是实例参数

2  代码分析:
    public static void main(String[] args) throws  Exception {
  // TODO Auto-generated method stub
  ClassLoader loader = Collection.class.getClassLoader();   //类加载器
  Class clazzProxy = Proxy.getProxyClass(loader, Collection.class);
  System.out.println(clazzProxy.getName());//类名
  
  Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);//这个InvocationHandler是形参
  
  Collection coll = ( Collection )constructor.newInstance( new InvocationHandler(){ //这个 InvocationHandler是实参,必须实现接口
   @Override
   public Object invoke(Object proxy, Method method, Object[] args)
     throws Throwable {
    // TODO Auto-generated method stub
    return null;
   }
  });//返回Collection的实例变量
  
  System.out.println(coll);//结果为null,但这是假象,实例已经建立
  coll.add(3);//出现异常,因为$Proxy类只有调用这个ClassLoader的功能,没有修删改的功能
  
  
 }
3   一步到位
  JVM动态生成的类
  */
 public static void main(String[] args)throws Exception {
  // TODO Auto-generated method stub
  
  /*一步到位
  public static Object newProxyInstance(ClassLoader loader,
                Class<?>[] interfaces,  //如果此对象表示一个类,则返回值是一个数组,它包含了表示该类所实现的所有接口的对象
                InvocationHandler h)*/
  
  //调用newProxyInstance方法
  Collection CollectionProxy =(Collection) Proxy.newProxyInstance(
    Collection.class.getClassLoader(), //类的加载器
    new Class []{ Collection.class},//类中所有对象的字节码
    new InvocationHandler(){ //实现的接口,接口包含Collection的方法

     @Override
     public Object invoke(Object proxy, Method method,
       Object[] args) throws Throwable {
          ArrayList list = new ArrayList();//定义一个集合
          /*Object obj  = method.invoke(proxy, args);//调用方法
          list.add(obj);*/: 如果这样,则会递归调用,出现死循环
          list.add(2);
          System.out.println(1);
      return list.toString();
     }
    }
    );
  4 分析:JVM动态生成的类
    动态生成的类实现了Collection接口(可以实现若干接口),生成的类有Collection接口中的所有方法和一个如下接受InvocationHandler参数的构造方法。
构造方法接受一个InvocationHandler对象,接受对象了要干什么用呢?该方法内部的代码会是怎样的呢?
    答:接受了InvocationHandler这个对象,则复写了invoke的方法,实现原来类的作用,它的内部的代码就是原来的类的代码构成。
    分析为什么动态类的实例对象的getClass()方法返回了正确结果呢?
    答:getClass()方法调用的是字节码,有实例对象就有字节码
    调用调用代理对象的从Object类继承的hashCode, equals, 或toString这几个方法时,代理对象将调用请求转发给InvocationHandler对象,对于其他方法,则不转发调用请求
 
 5 oop思想:封装,实现小小的框架
   代码一步一步的改进的,由点到面,体现了代码的阅读性,广泛性
   代码:
   JVM动态生成的类
  */
 public static void main(String[] args)throws Exception {
  
  final Object list = new Object();//定义一个集合
  Object obj = getProxy(list);
  
  for(int i=0;i<10;i++)
  {
   System.out.println(obj.equals("2"));
  }
 
   }

 public static Object getProxy(final Object ob) {
  Object proxy = Proxy.newProxyInstance(
    ob.getClass().getClassLoader(), //类的加载器
    ob.getClass().getInterfaces(),//类中所有对象的字节码
    new InvocationHandler(){ //实现的接口,接口包含Collection的方法
     public Object invoke(Object proxy, Method method,
       Object[] args) throws Throwable {
         
          new Myadvice().sartTime();
          Object obj= (Object)method.invoke(ob, args);
          new Myadvice().endTime();
          long allTime = new Myadvice().endTime()-new Myadvice().sartTime();
          System.out.println( method.getName()+": run times : "+allTime);
          return obj;
     }
    }
    );
  return proxy;
 }
 
}

 


接口:package cn.itcast.day20120726;

public interface advice {
 public  long sartTime();
 public long endTime();
 

}

实现接口的类

package cn.itcast.day20120726;

public class Myadvice implements advice {
 
 public long sartTime()
 {
  long sartTime = System.currentTimeMillis();
  System.out.println("我轻轻的来");
  return sartTime;
 }
 public long endTime()
 {
  long endTime = System.currentTimeMillis();
  System.out.println("我轻轻的走");
  return endTime;
 }

}

 

 

 

 


   ----------- android培训java培训、java学习型技术博客、期待与您交流! ------------
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值