0

我正在尝试编写一个类来获取一个巨型对象,并确保仅更改了某些字段,通常您会以这种方式注释/添加验证,但不幸的是,在这种情况下这不是一个选项,我唯一能做的change 是我正在处理的一个类,它将接收我应该以某种方式验证的非常大(并且非常嵌套!)的对象。

我最初的想法是制作一个可以更改的“列表”,然后遍历对象中的所有属性并检查是否有任何不在“白名单”上的更新,我有旧版本的对象,所以我可以对照旧的字段检查每个字段以确认,但我不完全确定如何执行此操作,或者是否有更好的解决方案。我以前从未尝试过这样的事情。

任何建议表示赞赏。如果没有更好的解决方案,我应该如何创建白名单/迭代大型对象的所有属性/嵌套属性?

更新: 根据建议,这是我正在尝试的,但它仍然存在一些问题(请注意,我只是在扔东西,这绝不是我的最后一堂课或好的编程):

  1. isTraversable 适用于集合,但我不确定如何检查自定义类,例如。一个 Person 类,它仍然需要迭代。
  2. 到处都有循环引用,也不知道如何处理它们。
public class Test {
       private Object obj1;
       private Object obj2;
       private List<String> whitelist;

        public void validate(Object objectToTraverse, 
                             Object objectToCompareTo, 
                             List<String> whitelist){
            this.obj1 = objectToTraverse;
            this.obj2 = objectToCompareTo;
            this.whitelist = whitelist;

            traverseAndCompare(obj1, obj2);
        }

        private void traverseAndCompare(Object objectToTraverse, 
                                        Object objectToCompareTo){
            try {
                for (Field field : objectToTraverse.getClass()
                        .getDeclaredFields()) {

                    field.setAccessible(true);
                    Object fieldValue = field.get(objectToTraverse);

                    if (isTraversable(field)) {
                        traverseAndCompare(field.get(objectToTraverse), 
                                field.get(objectToCompareTo));
                    } else {
                        getFieldValuesAndCompare(field, obj1, obj2);
                    }
                }
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }

        private boolean getFieldValuesAndCompare(Field field, 
                                                 Object obj1, 
                                                 Object obj2) 
                throws Exception{

            Object value1 = field.get(obj1);
            Object value2 = field.get(obj2);

            return compare(value1, value2);
        }

        private boolean compare(Object value1, 
                                Object value2){
            return Objects.equals(value1, value2);
        }

        private boolean isTraversable(Field field){
            // This should handle collections, but it does not work 
            // on custom classes, eg. Person class
            if (Collection.class.isAssignableFrom(field.getType())) {
                return true;
            }

            // Need to somehow figure out is this is a class with 
            // properties I can traverse, or something with a value, 
            // like String, Long, etc, hopefully
            // without listing everything

            return false;
        }
    }
4

1 回答 1

0

由于法律原因无法共享对象,因此给出描述性答案。

你有几个选择。各有利弊。

反射

您可以维护一个不允许更改的字段列表及其完整路径。像 abc 然后您可以编写纯反射代码或使用 http://commons.apache.org/proper/commons-beanutils/之类的常用工具来获取值(甚至在对象树的深处)并进行比较。

它需要更少的代码和更少的维护。但是您需要知道黑名单字段的确切列表。性能方面需要更多时间。

简单明码技术

在java中编写自己的比较器或方法来遍历所有无法更改和决定的字段。需要大量代码,但非常易于维护且性能最佳。

于 2020-02-28T21:57:51.320 回答