Могу ли я использовать аннотации Java для определения проверок времени компиляции?

Например, я хотел создать аннотацию @Out для целевых параметров. Тогда я бы каким-то образом использовал компилятор, чтобы проверить, установлено ли значение параметра до того, как функция вернется. Это возможно?

Также подумывал о аннотации @Immutable, которая не позволяла бы вызывать какой-либо метод, не аннотированный @Const, или доступ к любым открытым полям. (время компиляции и, возможно, время выполнения?)

Пока у меня есть это:

//I'm assuming Class retention is a subset of Runtime retention
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Out
{
    //no idea what to go in here.
}

это другая аннотация. опять же, у меня нет полного определения для этого:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Immutable
{

}

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

Это одна из тех вещей, которые вы думаете, «если бы это можно было сделать, это уже было бы там, и если это так, где я могу взять это».

редактировать: После дальнейших размышлений о@Const а также@Immutable и после запоминания Java передает указатели на объекты по значению, я расширил определение@Const, избавился от@Immutableи изменил определение@Out, как следует ниже:

/**
* When Applied to a method, ensures the method doesn't change in any
* way the state of the object used to invoke it, i.e., all the fields
* of the object must remain the same, and no field may be returned,
* unless the field itself is marked as {@code @Const}. A method 
* annotated with {@code @Const} can only invoke other {@code @Const}
* methods of its class, can only use the class's fields to invoke
* {@code @Const} methods of the fields classes and can only pass fields
* as parameters to methods that annotate that formal parameter as
* {@code @Const}.
*
* When applied to a formal parameter, ensures the method will not
* modify the value referenced by the formal parameter. A formal   
* parameter annotated as {@code @Const} will not be aliased inside the
* body of the method. The method is not allowed to invoke another 
* method and pass the annotated parameter, save if the other method 
* also annotates the formal parameter as {@code @Const}. The method is 
* not allowed to use the parameter to invoke any of its type's methods,
* unless the method being invoked is also annotated as {@code @Const}
* 
* When applied to a field, ensures the field cannot be aliased and that
* no code can alter the state of that field, either from inside the   
* class that owns the field or from outside it. Any constructor in any
* derived class is allowed to set the value of the field and invoke any
* methods using it. As for methods, only those annotated as
* {@code @Const} may be invoked using the field. The field may only be
* passed as a parameter to a method if the method annotates the 
* corresponding formal parameter as {@code @Const}
* 
* When applied to a local variable, ensures neither the block where the
* variable is declared or any nested block will alter the value of that 
* local variable. The local variable may be defined only once, at any
* point where it is in scope. Only methods annotated as
* {@code @Const} may be invoked using this variable, and the variable 
* may only be passed as a parameter to another method if said method
* annotates its corresponding formal parameter as {@code @Const}
*
*/
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD,
ElementType.LOCAL_VARIABLE})
@Inherited
public @interface Const
{

}

теперь@Out:

/**
* The formal parameter annotated with {@code @Out} must be undefined in 
* the scope of the caller, and it's the responsibility of the method to
* define it. If allowNull is true, the parameter can be explicitly set
* to null in the body of the method.
*/
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.PARAMETER)
public @interface Out
{
    boolean allowNull() default false;
}

Редактировать: Я пытаюсь реализовать это как плагин Eclipse, но я полностью потерял, читая руководство. Я написал плагин с основной логикой для доступа к AST и методов и полей посещения. Затем я сделал несколько фиктивных аннотаций, которые должен обнаружить мой плагин, затем я пытаюсь распечатать результаты, но я даже не уверен, чего ожидать. Мой плагин является плагином "Incremental Build". Вот код для этого, если бы кто-то мог взглянуть и просто объяснить мне несколько вещей. Я полностью потерян в этом API.

https://github.com/Starless2001/Plugin-for-Eclipse

Ответы на вопрос(1)

Ваш ответ на вопрос