首页 移动开发 在线交易 IT笔记 网络技术 操作系统 企业架构 数据库 考试认证 IT培训 开源软件 数据存储 行业资讯
大家都在看:java   开发   C#   oracle   mysql   android   web开发   学习   sqlserver   linux   asp   php   ajax   javascript   css   html
Java字节码
2014-05-19 10:12:42 来源: 作者:admin 栏目:软考等考 责任编辑:
[导读]http://asm.ow2.org/index.html (asm官方网址)http://download.forge.objectweb.org/ (asm下载的父级目录)http://download.forge.objectweb.org/asm/ (asm各个版本的下载地址)http://download.forge.objectweb.org/eclipse-update/ (asm的eclipse插件)笔者在这里略微..
http://asm.ow2.org/index.html  (asm官方网址)
http://download.forge.objectweb.org/  (asm下载的父级目录)
http://download.forge.objectweb.org/asm/  (asm各个版本的下载地址)
http://download.forge.objectweb.org/eclipse-update/  (asm的eclipse插件)

笔者在这里略微修改了asm官方例子中的Hello World代码。
下面的代码需要引用asm-5.0.2.jar和asm-commons-5.0.2.jar两个jar包。

Helloworld.java代码如下:
package com.shihuan.test;import java.io.FileOutputStream;import java.io.IOException;import java.io.PrintStream;import java.lang.reflect.InvocationTargetException;import org.objectweb.asm.ClassWriter;import org.objectweb.asm.MethodVisitor;import org.objectweb.asm.Opcodes;import org.objectweb.asm.Type;import org.objectweb.asm.commons.GeneratorAdapter;import org.objectweb.asm.commons.Method;public class Helloworld extends ClassLoader implements Opcodes {	/**	 * @param args	 * @throws IOException 	 * @throws SecurityException 	 * @throws InvocationTargetException 	 * @throws IllegalArgumentException 	 * @throws IllegalAccessException 	 */	public static void main(String[] args) throws IOException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, SecurityException {		// Generates the bytecode corresponding to the following Java class:        //        // public class Example {        // public static void main (String[] args) {        // System.out.println("Hello world!");        // }        // }        // creates a ClassWriter for the Example public class,        // which inherits from Object        ClassWriter cw = new ClassWriter(0);        cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/shihuan/test/MyExample", null, "java/lang/Object", null);                // creates a MethodWriter for the (implicit) constructor        MethodVisitor mw = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", "()V", null, null);        // pushes the 'this' variable        mw.visitVarInsn(Opcodes.ALOAD, 0);        // invokes the super class constructor        mw.visitMethodInsn(Opcodes.INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);        mw.visitInsn(Opcodes.RETURN);        // this code uses a maximum of one stack element and one local variable        mw.visitMaxs(1, 1);        mw.visitEnd();        // creates a MethodWriter for the 'main' method        mw = cw.visitMethod(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);        // pushes the 'out' field (of type PrintStream) of the System class        mw.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");        // pushes the "Hello World!" String constant        mw.visitLdcInsn("Hello world 11111!");        // invokes the 'println' method (defined in the PrintStream class)        mw.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);        mw.visitInsn(Opcodes.RETURN);        // this code uses a maximum of two stack elements and two local        // variables        mw.visitMaxs(2, 2);        mw.visitEnd();        // gets the bytecode of the Example class, and loads it dynamically        byte[] code = cw.toByteArray();        FileOutputStream fos = new FileOutputStream("D:/javaworksspace/javaasm/bin/com/shihuan/test/MyExample.class");   //用文件流写文件        fos.write(code);        fos.close();        Helloworld loader = new Helloworld();        Class<?> exampleClass = loader.defineClass("com.shihuan.test.MyExample", code, 0, code.length);        // uses the dynamically generated class to print 'Helloworld'        exampleClass.getMethods()[0].invoke(null, new Object[] { null });        // ------------------------------------------------------------------------        // Same example with a GeneratorAdapter (more convenient but slower)        // ------------------------------------------------------------------------        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);        cw.visit(Opcodes.V1_5, Opcodes.ACC_PUBLIC, "com/shihuan/test/MyExample", null, "java/lang/Object", null);        // creates a GeneratorAdapter for the (implicit) constructor        Method m = Method.getMethod("void <init> ()");        GeneratorAdapter mg = new GeneratorAdapter(ACC_PUBLIC, m, null, null, cw);        mg.loadThis();        mg.invokeConstructor(Type.getType(Object.class), m);        mg.returnValue();        mg.endMethod();        // creates a GeneratorAdapter for the 'main' method        m = Method.getMethod("void main (String[])");        mg = new GeneratorAdapter(Opcodes.ACC_PUBLIC+Opcodes.ACC_STATIC, m, null, null, cw);        mg.getStatic(Type.getType(System.class), "out", Type.getType(PrintStream.class));        mg.push("Hello world 22222!");        mg.invokeVirtual(Type.getType(PrintStream.class), Method.getMethod("void println (String)"));        mg.returnValue();        mg.endMethod();        cw.visitEnd();        code = cw.toByteArray();        loader = new Helloworld();        exampleClass = loader.defineClass("com.shihuan.test.MyExample", code, 0, code.length);        // uses the dynamically generated class to print 'Helloworld'        exampleClass.getMethods()[0].invoke(null, new Object[] { null });	}}


运行上面的代码:
Hello world 11111!
Hello world 22222!

到workspace目录下跟Helloworld.class文件同级目录会发现多了一个MyExample.class文件。


标签:
本站地址:/
版权所有:转载请注明出处!
分享到:
上一篇隐藏SWT控件 下一篇编程要用等宽字体
您可能还喜欢
暂无...
今日最新资讯 最新推荐信息
考试认证 更多
开发技术 更多
移动开发 更多

关于 | 合作伙伴 | 联系我们 | 友情链接 | 版权声明 | 网站制作 | 网站地图 | 加入收藏 | 设为首页

Copyright@2012-2016 京ICP备12027873号