【发布时间】:2014-11-10 08:14:35
【问题描述】:
我使用 ASM 生成基于类ToOverride 的超类。我想覆盖它的ToOverride::getValue 方法。提到的类看起来像:
public abstract class ToOverride {
Object getValue(String str, Object arg) throws Exception {
throw new IllegalStateException("PARENT!");
}
Object justMethod() {
return "test";
}
}
在普通的 java 中,预期的类应该是这样的:
public class GeneratedInheritor extends ToOverride {
@Override
Object getValue(String str, Object arg) throws Exception {
return str + arg;
}
}
我生成了后一个类,它产生了以下字节码。
// class version 49.0 (49)
// access flags 0x21
public class com/example/GeneratedInheritor extends com/example/ToOverride {
// access flags 0x1
public <init>()V
ALOAD 0
INVOKESPECIAL com/example/ToOverride.<init> ()V
RETURN
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x0
getValue(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/Object; throws java/lang/Exception
NEW java/lang/StringBuilder
DUP
INVOKESPECIAL java/lang/StringBuilder.<init> ()V
ALOAD 1
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
ALOAD 2
INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/Object;)Ljava/lang/StringBuilder;
INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
ARETURN
MAXSTACK = 2
MAXLOCALS = 3
}
使用以下ClassLoader加载生成的类:
class DynamicallyCreatedClassesLoader extends ClassLoader {
public Class defineClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length);
}
}
我还用 ASM*s CheckClassAdapter 测试了生成的字节码。没有发生错误。当我调用生成的类的 getValue 方法时,它会导致 java.lang.IllegalStateException: PARENT! 这意味着我重写的 GeneratedInheritor::getValue 方法根本没有被调用。但是我可以在GeneratedInheritor的方法列表中看到getValue方法(使用GeneratedInheritor.class::getDeclaredMethods)。
【问题讨论】:
标签: java classloader java-bytecode-asm overriding