java - 调用实现接口(interface)的泛型方法时出现错误 : java. lang.AbstractMethodError

标签 java generics javassist java-bridge-method

我正在尝试使用 javassist 以编程方式创建和编译一个实现接口(interface)的类(在运行时)。

每当我调用该动态类的实例时,都会收到以下错误:

java.lang.AbstractMethodError: FooImpl.test()Ljava/lang/Object;

这是我的界面

public class FooBarInterface<T> {
    public T getEntity();
}

这是一个示例实体

public class FooEntity {

    @Override
    public String toString() {
        return "Hello, Foo!";
    }
}

这是我如何以编程方式实现接口(interface)

public void test() {
    ClassPool classPool = ClassPool.getDefault();
    CtClass testInterface = classPool.get(FooBarInterface.class.getName());

    CtClass fooImpl = classPool.makeClass("FooImpl");

    fooImpl.addInterface(testInterface);
    CtMethod testMethod = CtNewMethod.make(
        "public com.test.FooEntity getEntity(){" +
            "return new com.test.FooEntity();" +
        "}",
        canImpl
    );

    fooImpl.addMethod(testMethod);

    fooImpl.writeFile();

    TestInterface<FooEntity> test = 
        (TestInterface<FooEntity>) fooImpl.toClass().newInstance();

    System.out.println(test.getEntity());

}

如果我将实现方法的返回类型更改为 Object,那么我不会收到错误,如下所示:

CtMethod testMethod = CtNewMethod.make(
    "public Object getEntity(){" +
        "return new com.test.FooEntity();" +
    "}",
    canImpl
);

然后我成功收到hello, Foo!。我同意将返回类型更改为 Object,但我想更多地了解为什么使用 Foo 类型返回会产生 AbstractMethodError

最佳答案

在 JVM 内部,不同返回类型的方法是不同的。类型删除后,FooBarEntity.getEntity() 返回类型为 Object。通过接口(interface)的调用将专门查找返回类型为 Object 的方法,因此您的实现必须返回 Object

通常,您的 Java 编译器会创建桥接方法,将具体方法的结果转发为已删除类型,但显然 Javassist 不会为您执行此操作(我没有使用过 Javassist,所以我不确定)。

有关如何使用桥接方法实现类型删除的更多信息,请参阅 official Java Tutorials topic on bridge methods .

关于java - 调用实现接口(interface)的泛型方法时出现错误 : java. lang.AbstractMethodError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23601363/

相关文章:

Java 泛型 : incompatible type required String; found: java. lang.String

java - Spring 教程: Error creating bean with name 'entityManagerFactory' defined in class path resource

java - 删除代码重复

generics - 如何在具有通用参数的结构上实现非通用特征

Java - 在 JVM 中修改 Object 类的 toString()

java - 奇怪的 java.lang.VerifyError

java - 使用 eclipse 导出可运行的 jar

java - 匹配 3 个或更多连续连续字符和连续相同字符的正则表达式

需要 Java SE 数组帮助

java - 如何防止并行线程中的异常杀死应用程序?