Ошибка Java: найден интерфейс ... но ожидался класс - PullRequest
31 голосов
/ 26 февраля 2009

Я получаю странную ошибку во время выполнения из моего кода:

"Found interface [SomeInterface] but class was expected"

Как это может произойти? Как создать экземпляр интерфейса?

Обновление: (В ответ на некоторые ответы) Я компилирую и работаю с тем же набором библиотек, но я am , используя Guice для введения Поставщик для этого конкретного интерфейса.

Проблема исчезла, когда я связал реализацию с интерфейсом (похоже, аннотации @ImplementedBy было недостаточно).

Меня больше интересовала механика, с помощью которой Guice удалось на самом деле создать интерфейс.

Ответы [ 5 ]

66 голосов
/ 26 февраля 2009

Это происходит, когда ваш путь к классу времени выполнения отличается от вашего пути к классу времени компиляции.

Когда ваше приложение было скомпилировано, класс (названный SomeInterface в вашем вопросе) существовал как класс.

Когда ваше приложение выполняется во время компиляции, SomeInterface существует как интерфейс (вместо класса.)

Это приводит к выбрасыванию IncompatibleClassChangeError во время выполнения.

Это распространенный случай, если у вас была другая версия файла JAR в пути к классам времени компиляции, чем в пути к классам времени выполнения.

6 голосов
/ 26 февраля 2009

Скорее всего, код был скомпилирован для класса в библиотеке, который затем был изменен на интерфейс в версии, с которой вы работаете.

2 голосов
/ 10 мая 2012

У меня была такая же проблема. Я использую две библиотеки JAR в моем приложении. Одна библиотека построена на другой.

Библиотека A определяет верхние классы и интерфейсы. Библиотека B требует библиотеки A.

Это псевдокод некоторого кода, используемого в библиотеке B:

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

Очевидно, библиотека A новее, чем библиотека B, и TheInterface больше не содержит someMethod, но TheClass по-прежнему содержит. Единственный способ исправить это - получить исходный код для любого jar-файла и изменить все вручную (если это возможно).

1 голос
/ 02 ноября 2018

Это случилось со мной, когда я управлял maven build.

Из того, что я мог собрать (а также из ответа Джареда ), поскольку причина была в том, что в моем действующем pom.xml были указаны две версии одного и того же стороннего банки Одна версия входила как транзитивная зависимость , а другая была указана мной в моем локальном pom.xml.

Таким образом, во время компиляции он имел в виду старую версию, а во время выполнения он имел в виду новую версию.

Я удалил версию, указанную в моем локальном pom.xml, и она заработала.

Конечно, сторонние разработчики нарушили обратную совместимость между своими версиями и изменили класс на интерфейс или наоборот. Но они могут это сделать.

1 голос
/ 26 февраля 2009

Звучит так, как ты

class MyClass extends SomeInterface

когда это должно быть на самом деле

class MyClass implements SomeInterface

Я прав?

РЕДАКТИРОВАТЬ: О, вы говорите, что это ошибка времени выполнения , а не ошибка времени компиляции ? Позвольте мне немного осмотреться ...

РЕДАКТИРОВАТЬ 2: Похоже, что Джаред имеет правильный ответ. В любом случае, попытка расширить интерфейс фактически выдает сообщение « интерфейс не ожидается здесь » во время компиляции, а не « найден интерфейс, но ожидается ошибка класса ».

...