繁体   English   中英

错误:调用实现接口的通用方法时,java.lang.AbstractMethodError

[英]Error: java.lang.AbstractMethodError when invoking a generic method implementing an interface

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

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

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

这是我以编程方式实现接口的方式

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 通过接口进行的调用将专门查找具有返回类型Object的方法,因此为什么您的实现必须返回Object

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

有关如何使用桥方法实现类型擦除的更多信息,请参见关于桥方法官方Java教程主题

当您有参数化的参数或返回类型时,Java编译器将其编译为好像是Object一样,并使用带有参数化签名的桥方法合成桥方法,该签名方法将调用另一个方法。 或可能相反。 您只合成了其中一个,而不是两者都合成。

我有同样的错误。 我有一个基类,在其中声明了一个新的抽象方法。 我在使用它的其他类上实现了该方法。 现在在调试时,一旦达到方法的实现,就会遇到Abstract方法错误。

解决方案:我发现基类也被其他工件占用,并且没有覆盖这些工件中新创建的抽象方法。 由于我从未更改过它们,所以我从未构建它们,因此JVM永远不会引发编译时错误,但会在运行时发生异常。 在其他工件中实现方法时,我能够摆脱异常。基本上在我的情况下,所有子类都没有实现基类的抽象方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM