Произвести условную ошибку времени компиляции в Java

StackOverflow https://stackoverflow.com/questions/88991

Вопрос

Я не имею в виду ошибки компиляции, потому что я допустил синтаксическую ошибку или что-то еще.В C++ мы можем создавать ошибки времени компиляции в зависимости от условий, как показано в следующем примере:

template<int> struct CompileTimeError;
template<> struct CompileTimeError<true> {};

#define STATIC_CHECK(expr, msg) { CompileTimeError<((expr) != 0)> ERROR_##msg; (void)ERROR_##msg; }

int main(int argc, char* argv[])
{
    STATIC_CHECK(false, Compile_Time_Failure);
    return 0;
}

В VS 2005 это выведет:

------ Build started: Project: Test, Configuration: Debug Win32 ------
Compiling...
Test.cpp
f:\temp\test\test\test.cpp(17) : error C2079: 'ERROR_Compile_Time_Failure' uses undefined struct 'CompileTimeError<__formal>'
        with
        [
            __formal=0
        ]
Build log was saved at "file://f:\temp\Test\Test\Debug\BuildLog.htm"
Test - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Есть ли способ добиться этого на Java?

Это было полезно?

Решение

В Java это невозможно сделать, как и в C++.

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

Например:

@MyStaticCheck(false, "Compile Time Error, kind-of")
public static void main(String[] args) {
    return;
}

А затем напишите свою собственную AnnotationProcessorFactory, которая ищет аннотации @MyStaticCheck и что-то делает с аргументами.

Примечание:Я не слишком много играл с apt, но из документации видно, что это вполне выполнимо.

Другие советы

В Java невозможно выполнить какие-либо действия на основе логики времени компиляции без использования отдельного инструмента.Технически это возможный использовать препроцессор C на Java, но вам придется быть осторожным с его встроенными предположениями о базовом языке.На вашем месте я бы нашел лучший способ добиться того, что вы пытаетесь сделать, с этой ошибкой времени компиляции.При необходимости вы даже можете написать свой собственный препроцессор (возможно, используя АПТ), если это действительно так неизбежно.

Как ответил Мэтт Куэйл выше, аннотации вместе с XDoclet, подходят для удовлетворения ваших потребностей.Эти комбинации позволяют выполнить значительную предварительную обработку, генерацию кода и т. д.

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

Специфика моей задачи требует, чтобы два приложения с разным набором функций были построены из одной базовой библиотеки (и неиспользуемые элементы не должны быть связаны).Выбор набора функций осуществляется public static final boolean флаги.Проблема в том, что я хочу убедиться, что каждое из приложений построено с правильным флагом, установленным в базовой библиотеке.А в случае включения неправильных функций приложение не должно компилироваться, выдавая ошибку времени компиляции.

Единственное решение, которое я нашел до сих пор, — это объявить в библиотеке конечные переменные вместе с флагами: public static final int functionSet1 = 0;, и т. д.

В пакет приложения я добавил фиктивный класс с проверкой

ConditionalBuild.functionSet1 = 1;

Из всех переменных functionSetX только одна стала нефинальной в конкретной сборке.Таким образом, только одно приложение может пройти процесс сборки без ошибки.Есть ли лучший способ добиться этого?Пожалуйста, дайте мне знать в комментариях.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top