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;
}