2017-01-09 9 views
1

я следующий класс аннотацииJava аннотации: с помощью значения поля в другое поле

public @interface Size { 
    int min() default 1; 
    int max() default 100; 
    String message() default "Age between min - max"; 
} 

Здесь по умолчанию message() Я хочу значение по умолчанию min() и max(). Просто писать String message() default "Age between" + min() + "-" + max(); здесь не работает. Есть ли прямой способ сделать это?

EDIT 1: У меня есть класс человека слишком

public class Person { 

    @Size(max = 10) 
    private String name; 

    @Size(min = 18, message = "Age can not be less than {min}") 
    private int age; 

    public Person(String s, int i) { 
    this.name = s; 
    this.age = i; 
    } 
} 

Теперь здесь значение min() и max() могут быть установлены. Поэтому, если пользователь вводит неверный ввод, тогда message() будет соответствующим образом принтером.

EDIT 2: As @nicolas хотел. Здесь класс AnnonatedValidator, который проверял входы и выводил сообщение об ошибке печати.

public class AnnotatedValidator { 

public static void validate(Person p, List<ValidationError> errors) { 

    try { 
     Field[] fields = p.getClass().getDeclaredFields(); 
     for(Field field : fields) { 
      if(field.getType().equals(String.class)){ 
       field.setAccessible(true); 
       String string = (String)field.get(p); 

       Annotation[] annotationsName = field.getDeclaredAnnotations(); 
       for (Annotation annotation : annotationsName){ 
        if (annotation instanceof Size){ 
         Size size = (Size) annotation; 
         if (string.length() < size.min() || string.length() > size.max()) { 
          error(size, errors); 
         } 
        } 
       } 

      } else if (field.getType().equals(int.class)) { 
       field.setAccessible(true); 
       int integer = (Integer)field.get(p); 

       Annotation[] annotationsAge = field.getDeclaredAnnotations(); 
       for (Annotation annotation : annotationsAge){ 
        if (annotation instanceof Size){ 
         Size size = (Size) annotation; 
         if (integer < size.min() || integer > size.max()) { 
          error(size,errors); 
         } 
        } 
       } 
      } 
     } 

    }catch (IllegalAccessException e) { 
     e.printStackTrace(); 
    } 
} 

public static void print(List<ValidationError> errors) { 
    for (int i = 0; i < errors.size(); i++){ 
     System.out.println("Errors: " + errors.get(i).getError()); 
    } 
} 

public static void error (Size size, List<ValidationError> errors) { 
    String error = size.message(); 
    if (!error.equals(null)) { 
     if (error.contains("min")) { 
      error = error.replace("min", ""+size.min()); 
     } 
     if (error.contains("max")){ 
      error = error.replace("max", ""+size.max()); 
     } 
    } 

    ValidationError v = new ValidationError(); 
    v.setError(error); 
    errors.add(v); 
} 
} 

ValidationError это другой класс, который просто сохраняет ошибки.

+1

значение аннотации должно быть постоянным, вы не можете назвать мин/макс – AdamSkywalker

+1

вам лучше управлять в коде, который будет печатать сообщение, так как только константы, как ожидается, в качестве значения по умолчанию, как уже пояснялось –

+0

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

ответ

3

Нет, default Значения для String типов должны быть постоянными выражениями, как Java Language Specification dictates.

Это ошибка времени компиляции, если тип элемента не соразмерен со значением элемента. Типа T элемент соизмерима со значением элемента V тогда и только тогда, когда один из следующих условий:

  • [...]
  • T не является типом массива и тип V является назначение совместимый (§5.2) с T, а также:
    • [...]
    • Если T примитивный тип или String, т hen V - постоянное выражение (§15.28).

призывание других аннотаций элемента не является постоянным выражение.

Вам потребуется обработать это в компоненте, который управляет использованием аннотации. Объявите сообщение default как некоторое специальное значение.

String message() default "REPLACE_ME"; 

затем проверьте его при построении сообщения.Например

Field field = ... // get 'age' field 
Size size = field.getAnnotation(Size.class); 
if (size != null) { 
    String message = size.message(); 
    if (message.equals("REPLACE_ME")) { 
     message = "Age between " + size.min() + " - " + size.max() + "."; 
    } 
} 
int min = size.min(); 
int max = size.max(); 
// if field is of type int 
int value = field.getInt(instance); 
if (value > max || value < min) { 
    throw new ConstraintViolationException(message); 
} 
+0

Я также решил эту проблему, заменив сообщение по умолчанию на значения min() и max(). Мне просто интересно, можно ли это сделать динамически, как упоминал @NicolasFilotto. –

 Смежные вопросы

  • Нет связанных вопросов^_^