42

我从我的代码中得到一个奇怪的运行时错误:

"Found interface [SomeInterface] but class was expected"

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

更新:(响应一些答案)我正在编译和运行同一组库,但我正在使用Guice为这个特定的接口注入一个提供程序。

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

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

4

5 回答 5

79

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

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

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

这会导致IncompatibleClassChangeError在运行时抛出一个。

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

于 2009-02-26T16:56:02.217 回答
8

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

于 2009-02-26T16:57:19.110 回答
2

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

库 A 定义了顶级类和接口。库 B 需要库 A。

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

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

显然库 A 比库 B 更新,TheInterface并且不再包含someMethod,但TheClass仍然包含。解决此问题的唯一方法是获取任一 jar 的源代码并手动更改这些内容(如果可能的话)。

于 2012-05-10T05:28:04.460 回答
2

这发生在我运行maven build.

从我能收集到的信息(以及 Jared 的回答),原因是 - 在我的有效文件中指定了同一个 3rd 方 jar 的两个版本pom.xml。一个版本是作为传递依赖项进来的,另一个是我在本地指定的pom.xml

所以在编译时,它指的是旧版本,而在运行时它指的是新版本。

我删除了本地指定的版本pom.xml并且它有效。

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

于 2018-11-02T16:18:23.577 回答
1

听起来你做了

class MyClass extends SomeInterface

实际上应该是什么时候

class MyClass implements SomeInterface

我对吗?

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

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

于 2009-02-26T16:54:15.187 回答