Как Eclipse может создать класс с неразрешенными проблемами компиляции?

Когда я пытаюсь скомпилировать этот класс с помощью javac, я получаю ошибку компиляции и Test.class не создается.

public class Test {
    public static void main(String[] args) {
        int x = 1L;  // <- this cannot compile
    }
}

Но когда я создаю этот класс в Eclipse, я вижу, что Test.class появляется в target/classes. Когда я пытаюсь запустить этот класс из командной строки с помощью java.exe, я получаю

Исключение в потоке "main" java.lang.Error: проблема неразрешенной компиляции:
      Тип несоответствия: невозможно преобразовать из long в int

Использует ли Eclipse собственный специальный компилятор Java для создания сломанного .class? Как java.exe знает о проблемах с компиляцией в .class?

Ответ 1

Вот как компилятор Java знает о ошибке компиляции в классе.

public static void main(String[] paramArrayOfString)
{
    throw new Error("Unresolved compilation problem: \n\tType mismatch: cannot convert from long to int.\n");
}

Если вы декомпилируете файл класса, вы можете увидеть выше описанный метод main() файла класса, который сгенерировал компилятор. Это связано с тем, что compiler, который использует Eclipse (Eclipse Compiler for Java), не совпадает с стандартным компилятором Java!

Ответ 2

Eclipse использует компилятор IBM, который имеет возможность создавать классы, которые не компилируются, заменяя ошибки на

throw new Error();

ИМХО, это очень плохая практика, и я видел, что некоторые проекты с очень низким качеством используют это. Проект не собирался полностью в течение недель за раз.

В отличие от быстрых стратегий отказа, которые пытаются минимизировать затраты на ошибки, обнаружение ошибок как можно позже также увеличивает затраты на их исправление.

Эта стратегия работает только в том случае, если вы быстро пишете код прототипа, т.е. код, который, как вы знаете, никогда не попадет в производство. (Трудно быть уверенным, что это будет так)

Ответ 3

Да, Eclipse использует свой собственный специальный компилятор; известный как "ecj". Из вопроса о переполнении стека В чем разница между javac и компилятором Eclipse?:

Одна заметная разница заключается в том, что компилятор Eclipse позволяет запускать код, который на самом деле не был правильно составлен. Если блок кода с ошибкой никогда не запускается, ваша программа будет работать нормально. В противном случае это вызовет исключение, указывающее, что вы пытались запустить код, который не компилируется.