2016-09-26 3 views
1

Я хотел бы иметь метод для проверки полого видаPassign имени атрибута в качестве параметра автоматически в Java-8

protected void validate(String field, String fieldName){ 
    if (field==null || field.isEmpty){ 
    throw new IllegalArgumentException("Parameter " + fieldName + " cannot be empty"); 
    } 
} 

и использовать в моем классе, например

class Foo { 
    private String x; 
    private String y; 

    ... 

    public void validateAll(){ 
    validate(x, "x"); 
    validate(y, "y"); 
    } 
} 

Было бы здорово использовать таким образом

public void validateAll(){ 
    validate(x); 
    validate(y); 
    } 

и позволяет компилятору автоматически передавать имя переменной для проверки (f ield, fieldName)

Как я могу добиться этого в Java-8?

+1

это невозможно. –

+0

Некоторый контекст того, где и почему вы хотите это сделать, поможет вам помочь (как, например, вы не должны пытаться это сделать, но используйте одну из многих проверяющих фреймворков). – Kirinya

ответ

0

Вы можете добиться этого на Java, отказавшись от идеи иметь классы java с полями и вместо этого иметь Map, который сопоставляет Column объектам значений. С точки зрения использования, это будет выглядеть примерно так:

public static final Column<String> X_COLUMN = new Column<>("x", String.class); 
public static final Column<String> Y_COLUMN = new Column<>("y", String.class); 
public static final Table FOO_TABLE = new Table("Foo", X_COLUMN, Y_COLUMN, ...); 
... 
Row fooRow = new Row(FOO_TABLE); 

fooRow.setFieldValue(X_COLUMN, "x"); 
String x = fooRow.getFieldValue(X_COLUMN); 

for(Column<?> column : fooRow.getTable().getColumns()) 
    doSomethingWithField(fooRow, column); 

private static <T> void doSomethingWithField(Row row, Column<T> column) 
{ 
    T value = row.getFieldValue(column); 
    ...do something with the field value... 
} 
+0

кажется довольно сложным подходом :-( – BlackBishop

+0

Вы бы предпочли комментарий «Это невозможно». C:: = –

0

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

class Foo { 
    private String x; 
    private String y; 

    //... 

    public void validateAll() { 
     for(Field f: Foo.class.getDeclaredFields()) { 
      if(!Modifier.isStatic(f.getModifiers()) && !f.getType().isPrimitive()) try { 
       Object o=f.get(this); 
       if(o==null || o.equals("")) 
        throw new IllegalArgumentException(f.getName()+" cannot be empty"); 
      } catch(ReflectiveOperationException ex) { throw new AssertionError(); } 
     } 
    } 
} 

Общая проблема этого подхода заключается в том, что к тому времени validateAll() сообщает о проблеме, экземпляр Foo уже содержит незаконное состояние. Предпочтительно отклонять недопустимые значения сразу, когда они пытаются установить свойство. В этом случае имя параметра метода может быть недоступным с точки зрения отражения, однако, когда метод с именем setX выдает IllegalArgumentException (как указано в трассировке стека), нет необходимости в дополнительной метаинформации в сообщении ...