簡體   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