WEB开发网
开发学院软件开发Java Java 编程的动态性,第 8 部分: 用代码生成取代反... 阅读

Java 编程的动态性,第 8 部分: 用代码生成取代反射

 2010-03-18 00:00:00 来源:WEB开发网   
核心提示: publicclassAccessValue1implementsIAccess{privateHolderBeanm_target;publicvoidsetTarget(Objecttarget){m_target=(HolderBean)target;}publicintgetValue(

public class AccessValue1 implements IAccess 
{ 
  private HolderBean m_target; 
   
  public void setTarget(Object target) { 
    m_target = (HolderBean)target; 
  } 
  public int getValue() { 
    return m_target.getValue1(); 
  } 
  public void setValue(int value) { 
    m_target.setValue1(value); 
  } 
} 

清单 2 接口设计为针对特定类型对象的特定属性使用。这个接口使实现代码简单了 —— 在处理字节码时这总是一个优点 —— 但是也意味着实现类是非常特定的。对于要通过这个接口访问的每一种类型的对象和属性,都需要一个单独的实现类,这限制了将这种方法作为反射的一般性替代方法。如果选择只在反射性能真正成为瓶颈的情况下才使用这种技术,那么这种限制就不是一个问题。

用 Javassist 生成

用 Javassist 为 清单 2 IAccess 接口生成实现类很容易 —— 只需要创建一个实现了这个接口的新类、为目标对象引用添加一个成员变量、最后再添加一个无参构造函数和简单实现方法。清单 4 显示了完成这些步骤的 Javassist 代码,它构造一个方法调用,这个方法以目标类和 get/set 方法信息为参数、并返回所构造的类的二进制表示:

清单 4. Javassist glue 类构造

/** Parameter types for call with no parameters. */ 
private static final CtClass[] NO_ARGS = {}; 
/** Parameter types for call with single int value. */ 
private static final CtClass[] INT_ARGS = { CtClass.intType }; 
protected byte[] createAccess(Class tclas, Method gmeth, 
  Method smeth, String cname) throws Exception { 
    
   // build generator for the new class 
   String tname = tclas.getName(); 
   ClassPool pool = ClassPool.getDefault(); 
   CtClass clas = pool.makeClass(cname); 
   clas.addInterface(pool.get("IAccess")); 
   CtClass target = pool.get(tname); 
    
   // add target object field to class 
   CtField field = new CtField(target, "m_target", clas); 
   clas.addField(field); 
    
   // add public default constructor method to class 
   CtConstructor cons = new CtConstructor(NO_ARGS, clas); 
   cons.setBody(";"); 
   clas.addConstructor(cons); 
    
   // add public setTarget method 
   CtMethod meth = new CtMethod(CtClass.voidType, "setTarget", 
     new CtClass[] { pool.get("java.lang.Object") }, clas); 
   meth.setBody("m_target = (" + tclas.getName() + ")$1;"); 
   clas.addMethod(meth); 
    
   // add public getValue method 
   meth = new CtMethod(CtClass.intType, "getValue", NO_ARGS, clas); 
   meth.setBody("return m_target." + gmeth.getName() + "();"); 
   clas.addMethod(meth); 
    
   // add public setValue method 
   meth = new CtMethod(CtClass.voidType, "setValue", INT_ARGS, clas); 
   meth.setBody("m_target." + smeth.getName() + "($1);"); 
   clas.addMethod(meth); 
    
   // return binary representation of completed class 
   return clas.toBytecode(); 
} 

上一页  1 2 3 4 5 6 7 8  下一页

Tags:Java 编程 动态性

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接