如何生成字节码并保存到.class文件?

时间:2011-10-14 10:22:12

标签: java reflection bytecode

我有以下奇怪的要求。

我得到了:

  1. 一些方法名称的列表。
  2. 上述方法的名称和参数类型。
  3. 上述方法的功能。具体如下: 对于每个参数,该方法使用toString将其转换为字符串,并获取字符串数组。对于此数组,该方法应用函数foo。函数fooString []类型作为输入,并输出String。这些方法返回foo返回的内容。 foo的代码在Java对象中给出,并作为黑盒子进行访问。
  4. 1.和2.中的信息可以是文本或XML文件。为此,我们可以认为它以我们选择的任何方式在Java对象中可用。

    任务是创建一个.class文件(即字节码)来实现这些方法,并且可以在JVM上运行。

    我认为this assembler library是一种方法。谁能建议一个更简单的方法?

    [编辑:]我可以想到另一种方式:首先生成.java文件然后编译它以获取.class文件。

    [上下文:]我必须为数百种方法执行此操作。我想要快捷方式,这样我就可以自动完成工作而不是手动编写代码。

3 个答案:

答案 0 :(得分:8)

您可以使用Java语法生成所需的程序代码,并使用编译器将其转换为类文件。可以在运行时实例化javac并将其传递给字节数组而不是源文件的位置。对于其他程序员来说,这可能是最容易维护的。

如果要直接生成字节代码,asm是最常用的库。

答案 1 :(得分:6)

以下是开源字节码库的列表:http://java-source.net/open-source/bytecode-libraries

看看Javassist

答案 2 :(得分:1)

我看到你回答了我的评论,但我仍然不清楚你为什么要生成代码然后打包在jar中,只需输入它:)

现在,如果你想要一个具有相同行为的所有方法的typesafe api,你可以为给定的接口提供动态代理(这会让你产生关于如何生成接口的问题:)

这是一个示例,其中所有MyInterface方法的所有调用都将由invoke方法处理(只需向接口添加方法来测试它)...

package test;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class Test {

interface MyInterface {

    String methodOne(String s);

    String methodTwo(String s, Integer i);
}

static MyInterface proxy = (MyInterface) Proxy.newProxyInstance(
        MyInterface.class.getClassLoader(),
        new Class[] { MyInterface.class }, new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {  
                StringBuilder result = new StringBuilder();
                for (Object arg : args) {
                    result.append(arg.toString());
                }
                return result.toString();
            }
        });

public static void main(String[] args) {
    System.out.println(proxy.methodOne("hello"));       
    System.out.println(proxy.methodTwo("world", 5));

}   

}