比较几个javabean属性的最佳方法是什么?

tpu*_*nen 14 java reflection

我需要比较两个对象(同一个类的实例)中的几十个字段,并在存在差异时进行一些日志记录和更新.元代码看起来像这样:

if (a.getfield1 != b.getfield1)
  log(a.getfield1 is different than b.getfield1)
  b.field1 = a.field1

if (a.getfield2!= b.getfield2)
  log(a.getfield2 is different than b.getfield2)
  b.field2 = a.field2

...

if (a.getfieldn!= b.getfieldn)
  log(a.getfieldn is different than b.getfieldn)
  b.fieldn = a.fieldn
Run Code Online (Sandbox Code Playgroud)

所有比较的代码非常简洁,我想以某种方式使它更紧凑.如果我有一个方法可以作为参数方法调用setter和getter,并为所有字段调用它,那将是很好的,但不幸的是,这是不可能的java.

我提出了三个选项,每个选项都有自己的缺点.

1.使用反射API查找getter和setter
Ugly,如果字段名称发生变化,可能会导致运行时错误

2.将字段更改为public并直接操作它们而不使用getter和setter
丑陋并将该类的实现暴露给外部世界

3.让包含类(实体)进行比较,更新已更改的字段并返回日志消息
实体不应参与业务逻辑

所有字段都是字符串类型,如果需要,我可以修改拥有字段的类的代码.

编辑:该类中有一些字段不得比较.

Dav*_*ria 16

使用注释.

如果您标记需要比较的字段(无论它们是否为私有字段,您仍然不会丢失封装,然后获取这些字段并进行比较.它可能如下所示:

在需要比较的类中:

@ComparableField 
private String field1;

@ComparableField
private String field2;

private String field_nocomparable;
Run Code Online (Sandbox Code Playgroud)

而在外部类:

public <T> void compare(T t, T t2) throws IllegalArgumentException,
                                          IllegalAccessException {
    Field[] fields = t.getClass().getDeclaredFields();
    if (fields != null) {
        for (Field field : fields) {
            if (field.isAnnotationPresent(ComparableField.class)) {
                field.setAccessible(true);
                if ( (field.get(t)).equals(field.get(t2)) )
                    System.out.println("equals");
                field.setAccessible(false);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

代码未经过测试,但如果有帮助请告诉我.

  • 请注意使用此功能的人:记住为注释界面定义@Retention(RetentionPolicy.RUNTIME). (3认同)
  • 上面的代码不完整,它不会访问属于超级类的字段 - 为此,您将需要一些递归。 (2认同)