Как поставить значение для аннотации из константы Java - PullRequest
127 голосов
/ 14 января 2010

Я думаю, что это может быть невозможно в Java, потому что аннотация и ее параметры разрешаются во время компиляции. У меня интерфейс выглядит следующим образом:

public interface FieldValues {
   String[] FIELD1 = new String[]{"value1", "value2"};
}

и другой класс как,

@SomeAnnotation(locations = {"value1", "value2"})
public class MyClass {
   ....
}

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

@SomeAnnotation(locations = FieldValues.FIELD1)
public class MyClass {
   ....
}

Однако это дает ошибки компиляции, такие как значение аннотации должно быть инициализатором массива и т. Д. Кто-нибудь знает, как я могу использовать константу String или константу String [] для предоставления значения аннотации?

Ответы [ 5 ]

113 голосов
/ 15 января 2010

Скомпилировать константы могут быть только примитивы и строки :

15,28. Постоянные выражения

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

  • Литералы примитивного типа и литералы типа String
  • Приведение к примитивным типам и приведение к типу String
  • [...] операторы [...]
  • Выражения в скобках, содержащиеся выражения которых являются константными.
  • Простые имена, которые ссылаются на постоянные переменные.
  • Квалифицированные имена формы TypeName . Идентификатор , относящийся к постоянным переменным.

На самом деле в Java нет способа защитить элементы в массиве. Во время выполнения кто-то всегда может сделать FieldValues.FIELD1[0]="value3", поэтому массив не может быть действительно постоянным, если мы посмотрим глубже.

34 голосов
/ 14 января 2010

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

import org.junit.Test;
import static org.junit.Assert.*;

public class MyTestClass
{
    private static final int TEST_TIMEOUT = 60000; // one minute per test

    @Test(timeout=TEST_TIMEOUT)
    public void testJDK()
    {
        assertTrue("Something is very wrong", Boolean.TRUE);
    }
}

Обратите внимание, что константу TEST_TIMEOUT можно передать прямо в аннотацию.

Случайно, я не помню, чтобы когда-либо пробовал это с массивом, поэтому вы можете столкнуться с некоторыми проблемами с небольшими различиями в том, как массивы представляются в виде параметров аннотации по сравнению с переменными Java? Но что касается другой части вашего вопроса, вы можете без проблем использовать постоянную строку.

РЕДАКТИРОВАТЬ: я только что попробовал это с массивом String, и не столкнулся с проблемой, которую вы упомянули - однако компилятор сказал мне, что "значение атрибута должно быть постоянным", несмотря на массив определяется как public static final String[]. Возможно, ему не нравится тот факт, что массивы изменчивы? Хм ...

10 голосов
/ 14 января 2010

Вы не предоставляете ему массив в вашем примере. Следующие компиляции отлично:

   public @interface SampleAnnotation {
        String[] sampleValues();
    }

    public class Values {
        public static final String v1 = "A";
        public static final String v2 = "B";

        @SampleAnnotation(sampleValues = { v1, v2 })
        public void foo() {
        }
    }
7 голосов
/ 14 января 2010

Кто-нибудь знает, как я могу использовать Строковая константа или String [] константа поставить значение для аннотации?

К сожалению, вы не можете сделать это с массивами. Для переменных, не являющихся массивами, значение должно быть окончательным статическим.

5 голосов
/ 10 ноября 2011

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

С помощью шва 2 http://seamframework.org/ вы смогли разрешить параметры аннотаций во время выполнения с помощью языка выражений в двойных кавычках.

В Seam 3 этой функцией является модуль Seam Solder http://seamframework.org/Seam3/Solder

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