在Java-8中自动将属性名作为参数进行传递
我想有一个方法来验证字段的类型在Java-8中自动将属性名作为参数进行传递,java,reflection,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; pri
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类的想法,而是使用一个将
列
对象映射到值的映射。从使用角度来看,大致如下所示:
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...
}
public static final Column X_Column=新列(“X”,String.class);
公共静态最终列Y_Column=新列(“Y”,String.class);
公共静态最终表FOO_Table=新表(“FOO”,X_列,Y_列,…);
...
行foorrow=新行(FOO_表);
setFieldValue(X_列,“X”);
字符串x=foorw.getFieldValue(x_列);
for(列:fooRow.getTable().getColumns())
doSomethingWithField(foorw,column);
私有静态void doSomethingWithField(行、行、列)
{
T值=行。getFieldValue(列);
…对字段值执行某些操作。。。
}
您可以在Java中实现这一点,方法是放弃使用带有字段的Java类的想法,而是使用将列
对象映射到值的映射。从使用角度来看,大致如下所示:
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...
}
public static final Column X_Column=新列(“X”,String.class);
公共静态最终列Y_Column=新列(“Y”,String.class);
公共静态最终表FOO_Table=新表(“FOO”,X_列,Y_列,…);
...
行foorrow=新行(FOO_表);
setFieldValue(X_列,“X”);
字符串x=foorw.getFieldValue(x_列);
for(列:fooRow.getTable().getColumns())
doSomethingWithField(foorw,column);
私有静态void doSomethingWithField(行、行、列)
{
T值=行。getFieldValue(列);
…对字段值执行某些操作。。。
}
由于作为参数传递给方法的值不包含有关其来源字段的任何信息,如果它是从字段中读取的,则无法重建此信息。但是,由于您的目的是验证字段,因此在首先处理字段而不是其包含的值时,可以执行所需的操作:
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
时,该方法的参数名可能不可用(如堆栈跟踪所示),消息中不需要额外的元信息…,因为作为参数传递给方法的值不包含有关其来源字段的信息,如果它是从字段读取的,则无法重建此信息。但是,由于您的目的是验证字段,因此在首先处理字段而不是其包含的值时,可以执行所需的操作:
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
时,该方法的参数名可能不可用(如堆栈跟踪所示),消息中不需要额外的元信息…这是不可能的。有关您希望在何处以及为什么这样做的一些上下文将帮助您(例如,您可能不应该尝试这样做,而是使用许多验证框架中的一个)。这是不可能的。有关您希望在何处以及为什么这样做的一些上下文将有助于您(例如,您可能不应该尝试这样做,而是使用许多验证框架中的一个)。这似乎是一种非常复杂的方法:-(您是否更喜欢“这是不可能的”。注释?C-:=这似乎是一种非常复杂的方法:-(您是否更喜欢“这是不可能的。”评论?C-:=