我想有一个方法来验证字段类型
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中实现这个?
您可以在Java中通过放弃使用带有字段的Java类的想法来实现这一点,而是使用将Column
对象映射为值的Map
。从使用的角度来看,它大致如下所示:
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...
}
由于作为参数传递给方法的值不包含有关其来源字段的信息,因此如果是从字段中读取的,则无法重构该信息。但是,由于您的目的是验证字段,因此在首先处理字段时,而不是处理它们所包含的值时,可以进行所需的操作:
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
时(正如堆栈跟踪所指示的那样),则不需要在消息中添加额外的元信息…