Как предоставить значение аннотации из константы java



Я думаю, что это может быть невозможно в 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[] для предоставления значения аннотации?

669   5  

5 ответов:

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

15.28. Постоянные Выражения

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

  • литералы примитивного типа и литералы типа String
  • приводит к примитиву типы и приведения к типу String
  • [...] операторы.[ ..]
  • заключенные в скобки выражения, содержащее выражение является постоянным выражением.
  • простые имена, которые ссылаются на постоянные переменные.
  • полные имена вида Имя_типа . идентификатор которые относятся к постоянным переменным.

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

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

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? Но что касается другой части вашего вопроса, Вы могли бы использовать константную строку без каких-либо проблем.

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

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

   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() {
        }
    }

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

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

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

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

в шве 3 Эта особенность припой шва модуля http://seamframework.org/Seam3/Solder

Comments

    Ничего не найдено.