java中的字节码

王朝java/jsp·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

这段时间一直在看java,看到讲 Reflection,ClassLoader,javassist 的地方,很兴奋,因为以前用.net的时候接触过一点点Reflection,但我再看到ClassLoader的时候,简直觉得非常神奇,可是神奇的东西一般都很难懂,看了很多资料,都不太明白,直到在ibm的网站上看到《java编程的动态性》,很详细的阐述了ClassLoader的作用,接着我看了使用javassist修改字节码的地方,跃跃欲试,动手做了一个小小的例子,朋友说我误入歧途,刚刚接触java就看这个东西,呵呵,不多说,看看代码就知道了。

AddMethod.java

/*

* Created on 2004-9-24

*

* TODO To change the template for this generated file go to

* Window - Preferences - Java - Code Style - Code Templates

*/

package cn.cpX.Parco.AddMethod;

import java.lang.reflect.*;

import javassist.*;

/**

* @author cpX.Parco

*

* TODO To change the template for this generated type comment go to

* Window - Preferences - Java - Code Style - Code Templates

*/

public class AddMethod {

/**

*

*/

public AddMethod() {

super();

// TODO Auto-generated constructor stub

}

private static void addMethod(CtClass clas)

{

try

{

String strOldMethod = "outputHello";

String strNewMethod = strOldMethod + "2";

/* //add new Method (copy)

* StringBuffer newMethodBody = new StringBuffer();

* CtMethod oldMethod = clas.getDeclaredMethod(strOldMethod);

* CtMethod newMethod = CtNewMethod.copy(oldMethod, strNewMethod, clas, null);

* newMethodBody.append("{System.out.println(\"Hello\");}");

* newMethod.setBody(newMethodBody.toString());

* clas.addMethod(newMethod);

*/

//add new Method (create)

CtClass []arrClas = new CtClass[0];

CtClass []arrExce = new CtClass[0];

StringBuffer newMethodBody = new StringBuffer();

newMethodBody.append("{System.out.println(\"Hello\");}");

CtMethod newMethod = CtNewMethod.make(CtClass.voidType ,strNewMethod, arrClas, arrExce, newMethodBody.toString(), clas);

clas.addMethod(newMethod);

//invoke new Method

Class tmpClass = clas.toClass();

Object obj = tmpClass.newInstance();

Method method = tmpClass.getDeclaredMethod(strNewMethod, null);

method.invoke(obj, null);

}

catch(Exception e)

{

e.printStackTrace();

}

}

public static void main(String[] args) {

try

{

CtClass clas = ClassPool.getDefault().get("cn.cpX.Parco.AddMethod.SayHello");

addMethod(clas);

}

catch(NotFoundException e)

{

e.printStackTrace();

}

}

}

SayHello.java

/*

* Created on 2004-9-24

*

* TODO To change the template for this generated file go to

* Window - Preferences - Java - Code Style - Code Templates

*/

package cn.cpX.Parco.AddMethod;

/**

* @author cpX.Parco

*

* TODO To change the template for this generated type comment go to

* Window - Preferences - Java - Code Style - Code Templates

*/

public class SayHello {

/**

*

*/

public SayHello() {

super();

// TODO Auto-generated constructor stub

}

public void outputHello()

{

}

}

一开始的时候因为不知道用那个make方法,所以在SayHello里面放了一个空的outputHello,目的就是生成新的CtMethod时候使用的,查过文档后使用了make方法,使用make方法,可以不用依靠以前的outputHello方法,写得过程中,因为C++的影响,我把新的method的参数列表用了一个包含一个void.class的数组代替,结果不能通过编译,还有异常列表,是一个CtClass的数组,不能直接把Exception放进去,估计需要继承一下CtClass。这两个地方我曾经都用null做参数尝试过,可是都不能正常运行,可见java中的空数组和null是有很大区别的。字节码的修改还有很多方法和作用,大家可以一起研究一下。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
 
© 2005- 王朝網路 版權所有 導航