Передать массив перечислений в Groovy аннотации - PullRequest
0 голосов
/ 30 апреля 2018

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

@Target([ ElementType.METHOD, ElementType.TYPE ])
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@interface SomeCustomAnnotation {

  SomeEnum[] someValue()
}

_

class SomeDataFactory {

static final SOME_ENUM_ARRAY = [SOME_ENUM_1, SOME_ENUM_2].toArray()

  enum SomeEnum {
   SOME_ENUM_1, SOME_ENUM_2
   }
}

_

class SomeClass {

   @SomeAnnotation(someValue = [SOME_ENUM_1, SOME_ENUM_2]) //fine
   def someMethod1(){}

   @SomeAnnotation(someValue = SOME_ENUM_ARRAY ) //Groovyc: Expected enum value for attribute someValue in @com.somepackage.SomeAnnotation
   def someMethod2(){}
}

Есть идеи?

1 Ответ

0 голосов
/ 30 апреля 2018

Аннотации ожидают встроенных констант. То, чего вы пытаетесь достичь, не может быть сделано, даже если переменные объявлены как static и final ..

Учитывая, что вы уже используете отдельный класс для предоставления массива, вы можете заменить SomeAnnotation на его «провайдера».

Есть много способов сделать это, но вот пример, использующий другое перечисление:

enum SomeDataProvider {

    SOME_ENUM_ARRAY_PROVIDER([SOME_ENUM_1, SOME_ENUM_2]);

    private List<SomeAnnotation> array

    SomeDataProvider(def array) {
         this.array = array
    }

    public List<SomeAnnotation> getSomeEnumArray() {
       return array;
    }
}

Затем измените код объявления аннотации на:

@SomeAnnotation(someValue = SOME_ENUM_ARRAY_PROVIDER)
def someMethod2(){}

Конечно, вам нужно изменить ожидаемый тип на SomeCustomAnnotation:

@interface SomeCustomAnnotation {

  SomeDataProvider[] someValue()
}

И обработку для получения SomeEnum[] скорее по вызову:

methodg.getDeclaredAnnotation(SomeAnnotation.class)
       .someValue()
       .getSomeEnumArray();

Вы также можете заменить SomeDataProvider интерфейсом и заставить SomeAnnotation взять java.lang.Class объект.

...