在Java-8中自动将属性名称作为参数

时间:2016-09-26 15:45:27

标签: java reflection

我想有一种方法来验证字段的种类

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);
  }

让编译器自动将变量名称传递给validate(field,fieldName)方法

我如何在Java-8中实现这一目标?

2 个答案:

答案 0 :(得分:0)

你可以通过放弃使用带有字段的java类的想法,而不是使用MapColumn个对象映射到值来实现这一点。从使用的角度来看,它看起来大致如下:

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...
}

答案 1 :(得分:0)

由于作为参数传递给方法的值不包含有关其源自的字段的信息, if 它是从字段中读取的,因此无法重建此信息。但是,由于您打算验证字段,因此在首先处理字段时可以执行所需的操作,而不是包含它们的值:

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时(如堆栈跟踪所示),则不需要消息中的其他元信息...