Подтвердить что ты не робот

Ошибка javac: неконвертируемые типы с дженериками?

Есть несколько других вопросов SO, говорящих о генериках, компилирующих компилятор OK w/Eclipse, но не javac (т.е. Java: Generics обрабатывает differenlty в Eclipse и javac и Generics компилируется и запускается в Eclipse, но не компилируется в javac) - однако это выглядит несколько иначе.

У меня есть класс enum:

public class LogEvent {
   public enum Type {
       // ... values here ...
   }
   ...
}

и у меня есть другой класс с методом, который принимает произвольные объекты типов, происходящих из enum:

@Override public <E extends Enum<E>> void postEvent(
    Context context, E code, Object additionalData) 
{
    if (code instanceof LogEvent.Type)
    {
        LogEvent.Type scode = (LogEvent.Type)code;
    ...

Это отлично работает в Eclipse, но когда я делаю чистую построенную с помощью ant, я получаю пару ошибок: одну на линии instanceof, другую на литье:

443: inconvertible types
    [javac] found   : E
    [javac] required: mypackage.LogEvent.Type
    [javac]         if (code instanceof LogEvent.Type)
    [javac]             ^

445: inconvertible types
    [javac] found   : E
    [javac] required: com.dekaresearch.tools.espdf.LogEvent.Type
    [javac]             LogEvent.Type scode = (LogEvent.Type)code;
    [javac]                                                  ^

Почему это происходит, и как я могу обойти эту проблему, чтобы она правильно скомпилировалась?

4b9b3361

Ответ 1

Я не знаю, почему это происходит, но обходное решение очень просто:

@Override public <E extends Enum<E>> void postEvent(
    Context context, E code, Object additionalData) 
{
    Object tmp = code;
    if (tmp instanceof LogEvent.Type)
    {
        LogEvent.Type scode = (LogEvent.Type)tmp;
    ...

Это уродливо, но оно работает...

Ответ 2

Возможно, это потому, что вы объявили E как нечто, расширяющее Enum <E> . Я не могу сказать, что понимаю это полностью, но похоже, что он ограничивает набор типов некоторым подмножеством, которое по какой-то причине не может включать LogEvent.Type. Или, может быть, это просто ошибка в компиляторе. Я был бы счастлив, если бы кто-нибудь мог объяснить это более четко, но вот что вы можете сделать:

public <E extends Enum<?>> void postEvent(E code) 
{
    if (code instanceof LogEvent.Type)
    {
        LogEvent.Type scode = (LogEvent.Type)code;
        ...
    }
    ...

Это работает, и оно более элегантно, чем просто приведение к объекту.

Ответ 3

У меня была аналогичная проблема и она была обновлена ​​с jdk1.6.0_16 до jdk1.6.0_23, и она исчезла без каких-либо изменений кода.

Ответ 4

Чтобы использовать instanceof, оба операнда должны наследовать/реализовывать один и тот же класс/интерфейс.
E просто не может быть передан в LogEvent.Type

Я не знаю, как выглядит ваш полный метод, но это должно решить вашу проблему с помощью интерфейсов, а не Generics.

public interface EventType { }
public class LogEvent  {
    public enum Type implements EventType {}
}

public void postEvent(Context context, EventType code, Object additionalData) {
    if(code instanceof LogEvent.Type) {
    }
}