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

Я не имею в виду ошибки компиляции, потому что я допустил синтаксическую ошибку или что-то еще. В 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?

Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
0
723
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

Ответ принят как подходящий

В Java нет способа сделать это, не так, как это работает у вас в C++.

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

Например:

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

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

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

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

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

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

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

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

ConditionalBuild.functionSet1 = 1;

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

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