放牧代码和思想
专注自然语言处理、机器学习算法
    愛しさ 優しさ すべて投げ出してもいい

解决java: 程序包javassist不存在

今天在看Thinking in Java的时候,配置工程出现错误:

java: 程序包javassist不存在

原因就像错误描述的那样,缺少javassist.jar包。本来应该是不值一提的错误,但是hankcs还是初次接触这个javassist.jar,还是得查查做个memo。它是JBoss的一个子项目,可以直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。你可以在这里下载到。这玩意儿可真是个狠家伙,可以动态生成\注入代码,修改已有的代码。令我回忆起windows上的线程注入dll注入了。

Talking is cheap,show me the code:-D

假设我有一个class A

package com.hankcs;

import java.util.Arrays;

/**
 * @author Hankcs
 */
public class A
{
    private int[] a = new int[]{23, 35, 46, 12, 99, 48, 74};

    public void foo(int n)
    { //示意性的代码表示业务逻辑
        for (int i = 0; i < n; i++)
        {
            Arrays.sort(a);
        }
        System.out.println("class A.foo()");
    }
}

我想要在程序中动态改变A的代码,利用javassist.jar可以轻易做到:

package com.hankcs;

import javassist.*;

public class Main
{

    public static void main(String[] args) throws NotFoundException, CannotCompileException, IllegalAccessException, InstantiationException
    {
        // 获取com.hankcs.A这个类
        CtClass cc = ClassPool.getDefault().get("com.hankcs.A");
        // 获取A类中的foo方法
        CtMethod method = cc.getDeclaredMethod("foo");
        // 重新取个名字,待会儿还要调用
        method.setName("foo$impl");
        // 将foo方法复制出一个新的方法,新方法与元方法一摸一样
        CtMethod newMethod = CtNewMethod.copy(method, "foo", cc, null);
        // 用字串写动态代码
        StringBuilder sb = new StringBuilder();
        sb.append("{\n");
        sb.append("    long start = System.currentTimeMillis();\n");
        sb.append("    foo$impl($$);\n");
        sb.append("    long end = System.currentTimeMillis();\n");
        sb.append("    System.out.println(\"Time interval = \" + (end - start) + \"ms\");\n");
        sb.append("}\n");
        // 将动态代码设为newMethod的Body
        newMethod.setBody(sb.toString());
        // 动态加入到类
        cc.addMethod(newMethod);
        // 生成实例
        A a = (A) cc.toClass().newInstance();
        // 输出Time interval =
        a.foo(10000000);
        // 依然输出Time interval =
        A b = new A();
        b.foo(10000000);
    }
}

输出:

class A.foo()
Time interval = 244ms
class A.foo()
Time interval = 192ms

Process finished with exit code 0

工程下载:http://pan.baidu.com/s/1BsHRh

参考http://hi.baidu.com/jackfrued/item/be340ce278b5daa8c10d75a1

知识共享许可协议 知识共享署名-非商业性使用-相同方式共享码农场 » 解决java: 程序包javassist不存在

评论 欢迎留言

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

我的作品

HanLP自然语言处理包《自然语言处理入门》