Java 使用ASM生成接口不起作用

Java 使用ASM生成接口不起作用,java,runtime,bytecode,.class-file,Java,Runtime,Bytecode,.class File,我需要在运行时生成一个接口。此接口将在中使用。起初,我是从谷歌上找到的,但后来我发现我可以用它来代替。下面是我获取接口字节码的代码: private static byte[] getBytecode(String internalName, String genericClassTypeSignature, Method[] methods, Class<?>... extendedInterfaces) throws IOException { ClassWriter c

我需要在运行时生成一个接口。此接口将在中使用。起初,我是从谷歌上找到的,但后来我发现我可以用它来代替。下面是我获取接口字节码的代码:

private static byte[] getBytecode(String internalName, String genericClassTypeSignature, Method[] methods, Class<?>... extendedInterfaces) throws IOException {
    ClassWriter cw = new ClassWriter(0);
    String[] interfaces = new String[extendedInterfaces.length];
    int i = 0;
    for (Class<?> interfac : extendedInterfaces) {
        interfaces[i] = interfac.getName().replace('.', '/');
        i++;
    }
    cw.visit(V1_6, ACC_PUBLIC + ACC_ABSTRACT + ACC_INTERFACE, internalName, null, "java/lang/Object", interfaces);
    ArrayList<String> exceptions = new ArrayList<String>();
    for (Method m : methods) {
        exceptions.clear();
        for (Class<?> exception : m.getExceptionTypes()) {
            exceptions.add(getInternalNameOf(exception));
        }
        cw.visitMethod(removeInvalidAbstractModifiers(m.getModifiers()) + ACC_ABSTRACT, m.getName(), getMethodDescriptorOf(m), getTypeSignatureOf(m), exceptions.toArray(new String[exceptions.size()]));
    }
    cw.visitEnd();
    return cw.toByteArray();
}

private static int removeInvalidAbstractModifiers(int mod) {
    int result = 0;
    if (Modifier.isProtected(mod)) {
        result += ACC_PROTECTED;
    }
    if (Modifier.isPublic(mod)) {
        result += ACC_PUBLIC;
    }
    if (Modifier.isTransient(mod)) {
        result += ACC_VARARGS;
    }
    return result;
}
Modifier.toString(0x404)
告诉我
0x404
表示
受保护的摘要。据我所知,
抽象类中的
受保护的抽象
方法是完全合法的

以下是
JFrame
paramString
方法(见上文)的代码:

/**
 * Returns a string representation of this <code>JFrame</code>.
 * This method
 * is intended to be used only for debugging purposes, and the
 * content and format of the returned string may vary between
 * implementations. The returned string may be empty but may not
 * be <code>null</code>.
 *
 * @return  a string representation of this <code>JFrame</code>
 */
protected String paramString() {
    String defaultCloseOperationString;
    if (defaultCloseOperation == HIDE_ON_CLOSE) {
        defaultCloseOperationString = "HIDE_ON_CLOSE";
    } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
        defaultCloseOperationString = "DISPOSE_ON_CLOSE";
    } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
        defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
    } else if (defaultCloseOperation == 3) {
        defaultCloseOperationString = "EXIT_ON_CLOSE";
    } else defaultCloseOperationString = "";
    String rootPaneString = (rootPane != null ?
                             rootPane.toString() : "");
    String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
                                            "true" : "false");

    return super.paramString() +
    ",defaultCloseOperation=" + defaultCloseOperationString +
    ",rootPane=" + rootPaneString +
    ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
}

我看不出我为什么会犯这个错误。有人能给我解释一下吗?

接口中的方法必须是
public


另外,在
removeInvalidAbstractModifiers()
方法中,应该使用
=
设置标志,而不是
+=
。如果已经设置了标志,则后者将导致问题(我知道如果从0开始,则不会出现问题,但这是一个好习惯)。虽然您为什么要在名为“remove”的方法中设置标志,但我不知道。

接口中的方法必须是
public


另外,在
removeInvalidAbstractModifiers()
方法中,应该使用
=
设置标志,而不是
+=
。如果已经设置了标志,则后者将导致问题(我知道如果从0开始,则不会出现问题,但这是一个好习惯)。虽然您为什么要在名为“remove”的方法中设置标志,但我不知道。

哦,我完全没有意识到接口方法必须是
public
。感谢您建议使用
|=
。我将该方法命名为“remove”,因为它只保留有效标志,就像“removing”无效标志一样。我一开始使用+=是因为ASM 4指南说要使用
ACC\u PUBLIC
+
ACC\u ABSTRACT
,尽管我不知道为什么。无论如何,非常感谢。哦,我完全没有意识到接口方法必须是
公共的
。感谢您建议使用
|=
。我将该方法命名为“remove”,因为它只保留有效标志,就像“removing”无效标志一样。我一开始使用+=是因为ASM 4指南说要使用
ACC\u PUBLIC
+
ACC\u ABSTRACT
,尽管我不知道为什么。无论如何,非常感谢你。
/**
 * Returns a string representation of this <code>JFrame</code>.
 * This method
 * is intended to be used only for debugging purposes, and the
 * content and format of the returned string may vary between
 * implementations. The returned string may be empty but may not
 * be <code>null</code>.
 *
 * @return  a string representation of this <code>JFrame</code>
 */
protected String paramString() {
    String defaultCloseOperationString;
    if (defaultCloseOperation == HIDE_ON_CLOSE) {
        defaultCloseOperationString = "HIDE_ON_CLOSE";
    } else if (defaultCloseOperation == DISPOSE_ON_CLOSE) {
        defaultCloseOperationString = "DISPOSE_ON_CLOSE";
    } else if (defaultCloseOperation == DO_NOTHING_ON_CLOSE) {
        defaultCloseOperationString = "DO_NOTHING_ON_CLOSE";
    } else if (defaultCloseOperation == 3) {
        defaultCloseOperationString = "EXIT_ON_CLOSE";
    } else defaultCloseOperationString = "";
    String rootPaneString = (rootPane != null ?
                             rootPane.toString() : "");
    String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
                                            "true" : "false");

    return super.paramString() +
    ",defaultCloseOperation=" + defaultCloseOperationString +
    ",rootPane=" + rootPaneString +
    ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
}