Java错误:找到了接口......但是预期了类

时间:2009-02-26 16:49:47

标签: java guice

我的代码中出现了一个奇怪的运行时错误:

"Found interface [SomeInterface] but class was expected"

这怎么可能发生?如何实例化接口?

更新(回答一些答案)我正在针对同一组库进行编译和运行,但我使用Guice注入此特定接口的提供者。

当我将一个实现绑定到接口时,问题就消失了(似乎@ImplementedBy注释还不够)。

我对Guice设法实际实例化接口的机制更感兴趣。

5 个答案:

答案 0 :(得分:65)

当您的运行时类路径与编译时类路径不同时,会发生这种情况。

编译应用程序时,一个类(在你的问题中名为SomeInterface)作为一个类存在。

当您的应用程序在编译时运行时,SomeInterface作为接口(而不是类)存在。

这会导致在运行时抛出IncompatibleClassChangeError

如果编译时类路径上的jar文件版本与运行时类路径上的版本不同,则这是常见的。

答案 1 :(得分:6)

很可能代码是针对库中的类编译的,然后将其更改为您运行的版本中的接口。

答案 2 :(得分:2)

我遇到了同样的问题。我在我的应用程序中使用了两个jar库。一个图书馆建立在另一个图书馆之上。

库A定义了顶级类和接口。图书馆B需要图书馆A.

这是库B中使用的一些代码的伪代码:

TheInterface instance = new TheClass();
instance.someMethod();

显然,库A比库B更新,TheInterface不再包含someMethod,但TheClass仍然存在。解决这个问题的唯一方法是获取罐子的来源并手动更改这些东西(如果可能的话)。

答案 3 :(得分:1)

听起来像你做过

class MyClass extends SomeInterface

什么时候应该

class MyClass implements SomeInterface

我是对的吗?

编辑:哦,你说这是运行时错误而不是编译时错误?让我环顾四周......

编辑2:看起来Jared有正确的答案。无论如何,尝试扩展接口实际上会在编译时提供“ no interface expected ”消息,而不是“找到的接口,但是类是预期的”错误。

答案 4 :(得分:1)

这是在我运行maven build时发生的。

从我可以收集到的信息(以及从Jare​​d的answer那里)中获悉,原因是-我有效的pom.xml中指定了同一个第三方jar的两个版本。一种版本是transitive dependency,另一种版本是我在本地pom.xml中指定的。

因此,在编译时,它是指旧版本,而在运行时,它是指新版本。

我删除了在本地pom.xml中指定的版本,并且可以正常工作。

当然,第3方打破了其版本之间的向后兼容性,并将类更改为接口,反之亦然。但是他们可以这样做。