Различия в компиляции между Intellij, Maven и Eclipse - PullRequest
0 голосов
/ 28 ноября 2018

У меня запутанная проблема.Во-первых, вот минимальный пример кода:

public interface I {
  <T> T getValue();
}

public abstract class AC<T> {
  private T value;

  public T getValue() {
    return value;
  }

  public void setValue(T value) {
    this.value = value;
  }
}

public class C extends AC<Integer> implements I {
}

public class Main {
  public static void main(String[] args) {
    final C c = new C();
    c.setValue(1);
    final Integer i = c.getValue();
    System.out.println(i);
  }
}

Когда я пытаюсь скомпилировать с помощью javac, Intellij или Maven, я получаю сообщение об ошибке:

C не является абстрактным и делаетне переопределять абстрактный метод getValue () в I

Если я компилирую Программу в Eclipse, она компилируется успешно.

Кто-нибудь может мне объяснить, почему eclipse может справиться с этим, а все остальные нет?

Здесь мои версии программного обеспечения:

  • Eclipse 2018-09 (4.9.0)
  • Intellij 2018.1.3
  • Maven 3.3.1
  • Oracle JDK 8u181

ОБНОВЛЕНИЕ:

Я сообщаю об этой проблеме в Oracle, и они могут воспроизвести эту проблему.Это ошибка в компиляторе Oracle ( Java Bug Database )

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Maven и Intellij оба используют (по умолчанию) javac Oracle JDK, тогда как Eclipse имеет свой собственный Java-компилятор.

Какой компилятор, javac или компилятор Eclipse определяется здесь Спецификацией языка Java .

Я считаю, что компилятор Eclipse здесь правильный , так как ваш пример объединяет двавещи, которые работают независимо с обоими компиляторами без проблем:

  • Реализация интерфейса через наследование , например:
public class ImplementationViaInheritance {
    public static void main(String[] args) {
        System.out.println(new C1().getClass());
    }
}

class SuperC1 {
    public void foo() {};
}

interface I1 {
    void foo();
}

class C1 extends SuperC1 implements I1 {
    // implements I1 via inheritance from SuperC1
}
public class AbstractClassWithoutAbstractMethods {
    public static void main(String[] args) {
        System.out.println(new C2().getClass());
    }
}

abstract class SuperC2 {
    public void foo() {};
}

class C2 extends SuperC2 {
    // no methods
}
0 голосов
/ 28 ноября 2018

Поскольку вы реализуете интерфейс I из неабстрактного класса C , вам необходимо переопределить абстрактный метод getValue ().Отредактируйте ваш класс C следующим образом:

public class C extends AC<Integer> implements I {
    public T getValue() {
        return value;
    }
}

или вы можете реализовать I из класса AC , как вы реализовали метод getValue ()там.А из класса C просто расширить класс AC

public abstract class AC<T> implements I {
    private T value;

    public T getValue() {
        return value;
    }

    public void setValue(T value) {
      this.value = value;
    }
}

public class C extends AC<Integer> {

}
...