`

Java动态性--->4 java字节码操作---JAVAssist

 
阅读更多

 

 


 

 

0 Java字节码操作简介:



 

 



 

 

 

 

1 JAVAssist简介:

 



 

 



 

2 JAVAssist好处在于 在源码级别可以定义,不需要学习JVM指令

 

代码:

 

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;

/**
 * 可以使用XJad来打开class文件
 * 测试使用javassist生成一个新的类 class文件
 * 需要下载 javassist jar包
 * @author
 *
 */
public class Demo01 {
	public static void main(String[] args) throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.makeClass("com.bean.Emp");
		
		//创建属性
		CtField f1 = CtField.make("private int empno;", cc);
		CtField f2 = CtField.make("private String ename;", cc);
		cc.addField(f1);
		cc.addField(f2);
		
		//创建方法
		CtMethod m1 = CtMethod.make("public int getEmpno(){return empno;}", cc);
		CtMethod m2 = CtMethod.make("public void setEmpno(int empno){this.empno=empno;}", cc);
		cc.addMethod(m1);
		cc.addMethod(m2);
		
		//添加构造器
		CtConstructor constructor = new CtConstructor(new CtClass[]{CtClass.intType,pool.get("java.lang.String")}, cc);
		constructor.setBody("{this.empno=empno; this.ename=ename;}");
		cc.addConstructor(constructor);
		
		cc.writeFile("c:/myjava"); //将上面构造好的类写入到c:/myjava中 最后生成字节码
		System.out.println("生成类,成功!");
	}
}

 

 

 

API代码操作:

 

 

import java.lang.reflect.Method;
import java.util.Arrays;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;
import javassist.NotFoundException;

/**
 * 测试javassist的API
 * @author 尚学堂高淇 www.sxt.cn
 *
 */
public class Demo02 {
	/**
	 * 处理类的基本用法
	 * @throws Exception 
	 */
	public static void test01() throws Exception{
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("com.test.Emp");
		
		byte[] bytes = cc.toBytecode();
		System.out.println(Arrays.toString(bytes));
		
		System.out.println(cc.getName()); //获取类名
		System.out.println(cc.getSimpleName()); //获取简要类名
		System.out.println(cc.getSuperclass()); //获得父类
		System.out.println(cc.getInterfaces()); //获得接口
		
	}
	
	/**
	 * 测试产生新的方法
	 * @throws Exception 
	 */
	public static void test02() throws Exception{
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("com.test.Emp");
		
//		CtMethod m = CtNewMethod.make("public int add(int a,int b){return a+b;}", cc);
		
		CtMethod m = new CtMethod(CtClass.intType,"add",
				new CtClass[]{CtClass.intType,CtClass.intType},cc);
		m.setModifiers(Modifier.PUBLIC);
		m.setBody("{System.out.println(\"www.sxt.cn\");return $1+$2;}");
		
		cc.addMethod(m);
		
		//通过反射调用新生成的方法
		Class clazz = cc.toClass();
		Object obj = clazz.newInstance();  //通过调用Emp无参构造器,创建新的Emp对象
		Method method = clazz.getDeclaredMethod("add", int.class,int.class);
		Object result = method.invoke(obj, 200,300);
		System.out.println(result);
	}
	
	/**
	 * 修改已有的方法的信息,修改方法体的内容   
	 * @throws Exception
	 */
	public static void test03() throws Exception{
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("com.test.Emp");
		
		CtMethod cm = cc.getDeclaredMethod("sayHello",new CtClass[]{CtClass.intType});
		cm.insertBefore("System.out.println($1);System.out.println(\"start!!!\");");  // AOP 前置通知
		cm.insertAt(9, "int b=3;System.out.println(\"b=\"+b);");
		cm.insertAfter("System.out.println(\"end!!!\");");    // AOP 后置通知
		
		//通过反射调用新生成的方法
		Class clazz = cc.toClass();
		Object obj = clazz.newInstance();  //通过调用Emp无参构造器,创建新的Emp对象
		Method method = clazz.getDeclaredMethod("sayHello", int.class);
		method.invoke(obj, 300);
	}

	/**
	 * 属性的操作
	 * @throws Exception
	 */
	public static void test04() throws Exception{
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("com.test.Emp");
		
//		CtField f1 = CtField.make("private int empno;", cc);
		CtField f1 = new CtField(CtClass.intType,"salary",cc);
		f1.setModifiers(Modifier.PRIVATE);
		cc.addField(f1);
		
//		cc.getDeclaredField("ename");   //获取指定的属性
		
		//增加相应的set和get方法
		cc.addMethod(CtNewMethod.getter("getSalary", f1));;
		cc.addMethod(CtNewMethod.getter("setSalary", f1));;
		
	}
	
	/**
	 * 构造方法的操作
	 * @throws Exception
	 */
	public static void test05() throws Exception {
		ClassPool pool = ClassPool.getDefault();
		CtClass cc = pool.get("com.test.Emp");
		
		CtConstructor[] cs = cc.getConstructors();
		for (CtConstructor c : cs) {
			System.out.println(c.getLongName());
		}
	}
	
	
	public static void test06() throws Exception{
		 CtClass cc = ClassPool.getDefault().get("com.test.Emp"); 
		 Object[] all = cc.getAnnotations();
		 Author a = (Author)all[0]; 
		 String name = a.name();
		 int year = a.year();
		 System.out.println("name: " + name + ", year: " + year);

	}
	
	
	public static void main(String[] args) throws Exception {
		test06();
	}
}

 

 

  • 大小: 62.8 KB
  • 大小: 113.2 KB
  • 大小: 139.3 KB
  • 大小: 49.3 KB
分享到:
评论

相关推荐

    javassist-3.18.1-GA.jar

    总的来说,`javassist-3.18.1-GA.jar`是Javaassist库的一个稳定版本,提供了丰富的API和工具,用于在运行时操纵Java类的字节码。这对于理解和实现诸如Hibernate这样的高级框架的内部工作原理非常有帮助。通过阅读...

    javassist-3.15.0-GA

    - **字节码操作**:Javaassist通过字节码操作实现对类的修改,它可以解析.class文件,并允许用户以Java语法修改字节码。 2. **使用场景**: - **AOP(面向切面编程)**:在不修改源代码的情况下,插入切面代码,...

    javassist-3.18.0-ga

    总的来说,`javassist-3.18.0-ga.jar`是Java开发中一个强大的工具,对于那些需要在运行时操作字节码的项目来说,它是不可或缺的。通过理解和熟练使用Javaassist,开发者可以实现更多创新和灵活的编程策略。

    javassist-3.20.0-GA.zip

    Javaassist提供了API,允许开发者读取、修改和创建字节码,从而实现对Java类的动态操作。这对于AOP(面向切面编程)、代理、代码生成以及运行时优化等场景特别有用。 在Javassist中,`ClassPool`对象是核心组件,...

    借助jclasslib与javassist修改java class字节码

    `javassist`是一个强大的字节码编辑器和类文件操作库,它能够帮助开发者动态地创建或修改类定义。通过`javassist`,可以方便地添加方法、字段或修改现有方法的行为,而无需接触原始源代码。 ##### 2. jclasslib `...

    javassist-3.18.2-GA.jar

    Javaassist 是一个强大的 Java 字节码操作库,它允许开发者在运行时动态修改或创建类。这个库在软件开发中的主要用途是实现元编程,即在程序运行时修改程序的行为。`javassist-3.18.2-GA.jar` 是 Javaassist 的一个...

    javassist-3.7.ga.jar

    Javaassist 是一个强大的 Java 字节码操作库,它允许开发者在运行时动态修改或创建类。这个库在软件开发中的主要用途是实现元编程,即在程序运行时修改程序的行为。`javassist-3.7.ga.jar` 文件是 Javaassist 库的一...

    javassist-3.9.0.GA.jar.zip

    总的来说,"javassist-3.9.0.GA.jar.zip"提供的Javaassist库是一个强大的字节码操作工具,对于理解Java字节码以及在运行时修改代码有着重要的作用。开发者可以利用这个库轻松地实现复杂的编程任务,提高代码的可扩展...

    javassist试图简化Java字节码的编辑

    `javassist`库正是这样一个工具,它为Java字节码操作提供了一个简洁的API,试图降低这个过程的复杂性。在Java世界中,字节码编辑通常用于动态代理、AOP(面向切面编程)、性能优化以及调试等场景。 `javassist`库是...

    Thinking in Java Jar.rar_Thing In Java_fruity88_in_javassist-3.9

    在学习这部分内容时,读者可能需要创建一个名为`fruity88`的项目,并使用`javassist-3.9.0.jar`来实现某些动态类生成或字节码操作的功能。 总的来说,这个压缩包包含的资源是学习《Thinking in Java》第四版中关于...

    javassist-3.23.1-GA.rar

    Javaassist的核心功能在于它的字节码操作能力。通过这个库,开发者可以在程序运行时创建、修改或分析Java类。这种能力在实现AOP(面向切面编程)、动态代理、代码生成以及调试工具等方面非常有用。例如,开发者可以...

    javassist-3.7.ga.jar下载

    总的来说,`javassist-3.7.ga.jar`是Java开发中的一个重要工具,它提供了一种强大的方式来处理运行时的字节码,使得代码增强和动态生成变得简单。对于需要在运行时修改类或实现复杂功能的开发者来说,Javaassist是一...

    javassist,Java字节码工程工具包.zip

    Java字节码工程工具包,通常被称为Javassist,是一个开源项目,专为Java开发者提供了一种方便的方式来处理和操作字节码。Javassist在Java应用开发中扮演着重要的角色,尤其是在动态代理、AOP(面向切面编程)以及...

    javaagent+javassist

    Javaagent和javassist是Java开发中的两个重要工具,它们在软件开发中有着广泛的应用,特别是在动态代理、代码增强和字节码操作等领域。本篇将详细介绍这两个技术,并结合实际示例进行解析。 首先,让我们来了解`...

    Javassist如何操作Java 字节码

    Javassist是一个强大的Java字节码操作库,它允许开发者在运行时动态修改或创建类。Javassist的出现使得开发者无需深入理解底层字节码指令就能方便地操作类、方法和字段,降低了字节码操作的难度。下面将详细介绍...

    jboss-javassist和JByteMode整合包

    Javassist和JByteMode是两个强大的工具,分别在不同的场景下提供了便捷的Java字节码操作能力。本文将深入探讨这两个库以及它们在整合中的应用。 **Javassist简介** Javassist,全称为Java Assistant,是一个开源的...

    Javassist18版20版22版的jar包

    总结来说,Javassist是一个强大的工具,它简化了Java字节码操作,为开发者提供了动态修改和创建类的能力。随着版本的迭代,其功能也在不断扩展和完善,以适应Java语言的发展和用户的需求。在实际项目中,正确利用...

    动态代理-jdk、cglib、javassist.zip

    javassist是一个开源的分析、转换和操作Java字节码的库。相比于CGLIB,javassist提供了更高级的API,可以直接编辑类的字节码,而不仅仅是生成新的字节码。它不仅可以用作动态代理,还可以用于AOP(面向切面编程)和...

    javassist-3.7.GA.zip

    4. **简单API**:相比于其他字节码操作工具如ASM,Javaassist的API设计得更加友好和直观,使得开发者更容易上手。 在Struts2.2.1框架中,Javaassist可能被用于以下几个方面: 1. **拦截器(Interceptor)**:Struts...

Global site tag (gtag.js) - Google Analytics