当前位置: 首页 > 知识库问答 >
问题:

从Serviceloader获取的子类抛出AbstractMethodError

敖淮晨
2023-03-14

我正在尝试制作一个Java应用程序,它可以加载实现抽象类的插件,并且在ServiceLoader生成的实例中出现了AbstractMethodError。代码有点重,所以我在下面进行了简化。

首先,我有一个抽象类:

package stuff.TheAbstractClass;

public abstract class TheAbstractClass implements ClassInterface{
 //Stuff happens
}

它实现了以下接口:

package stuff.ClassInterface;

public interface ClassInterface {

    public String getClassName();

}

我有一个服务提供商,它扩展了抽象类,并在meta-inf/services文件夹中声明:

package anotherstuff.NotAbstractClass;

public final class NotAbstractClass extends TheAbstractClass implements ClassInterface{
    private String name = "Silent Bob";

    @Override
    public String getClassName() { return name; }

}

然后在主应用程序(实际上是另一个应用程序中的插件)上,我想找到扩展AbstractClass的所有类:

package stuff.TheApp;

import java.util.ServiceLoader;

public class TheApp {
    private String name;

    public final static TheApp INSTANCE = new TheApp();

    private TheApp() {
        ServiceLoader<TheAbstractClass> serviceLoader =
            ServiceLoader.load(TheAbstractClass.class);
        for (TheAbstractClass class: serviceLoader) {
            name = class.getClassName;
        }
}

我的应用程序确实发现NotAbstractClass。我知道这一点,因为在for循环中,我可以执行类。getName()它会给我另一个东西。NotAbstractClass),但给出了错误:java。lang.AbstractMethodError:stuff。抽象类。getClassName()Ljava/lang/String

我被难住了。有什么建议吗?谢谢你,佩德罗


共有2个答案

范修伟
2023-03-14

问题似乎不在于代码,而在于IDE(IntelliJ)。我删除了所有以前打包的罐子,并在没有改变任何东西的情况下制作了新的罐子,它神奇地工作了...所以这是一个IDE错误,而不是语言问题!然而,感谢@Joao和@hotzst花时间阅读。最好的,佩德罗

白博赡
2023-03-14

根据AbstractMethodError的API,您可以得到:

当应用程序尝试调用抽象方法时引发。通常,编译器会捕捉到该错误;仅当自上次编译当前执行的方法以来,某些类的定义发生了不兼容的更改时,才会在运行时发生此错误。

只要看看你的代码和评论,我就知道这只可能发生在运行时。

如果是这样,那么:

自上次编译当前执行的方法以来,某些类发生了不兼容的更改

在Java兼容的形式中进行了一些调整后,我测试了您的逻辑,没有问题。唯一似乎正在发生的事情是TheAbstractClass的任何子类的更改。

我做的另一件事是使用:resources/META-INF/services中的依赖项文件声明依赖项:

文件:

内容:

在这之后,我没有任何问题。

 类似资料:
  • 我在从mysql数据库检索子类别时遇到一些问题。我想显示父类别的子类别。我只能得到主类别的最后一个子类别。第一个子类别不显示**。在我的表**中,我有类别\u id和类别\u父\u id。其中类别\u父\u id对于父类别将为“0”。提前谢谢 当我删除

  • 有一种方法可以找到类的所有命名子类,而不需要为(OWLClass子类:reasoner.GetSubclasses(clazz,true).GetFlatened())使用推理器

  • Im编写了一个小的Android应用程序,它应该从npm JSON服务器获取数据。它会抛出一个异常。我确实使用AsyncTask扩展了connection类,并在“DoInBackground”中执行了代码,但它仍然抛出了一个异常。请帮帮我. 代码如下: logcat告诉我们:

  • 我试图在一个页面上显示来自两个类别的帖子(6) 我将如何将类别ID“7”添加到该代码中,以使所有内容都像上面解释的那样工作?提前谢谢!

  • 我试图在WooCommerce的子类别页面中查找父类别名称,即我有4个主要类别。 父母1 子1 子2 子3等 父母2 子1 子2 子3等 等等。 如果我在Sub2的列表页上,Sub2是Parent1的子级,我想知道Parent1类别的名称。

  • 我们使用带有Log4j的springaop来登录我们的应用程序。我在应用程序中实现了@Before、@After、@posterhrowing建议。但我面临以下问题: 当任何异常在catch块中被捕获时,它不会调用@afterhrowing通知来打印错误堆栈跟踪。 我想为catch块中捕获的异常打印“错误堆栈跟踪”。意味着无论何时在try块中发生任何异常并被catch捕获,都应该调用一些建议来打印