Java-使用反射的比较字段

Java-使用反射的比较字段,java,Java,我需要比较两个对象的所有字段并返回差异数 伪代码如下所示: public int differentFields(Foo foo1, Foo foo2) { int differentFields = 0; for all fields of foo1 and foo2: if foo1.field[i] != foo2.field[i] differentFields++; return differentFields; } 字段具有

我需要比较两个对象的所有字段并返回差异数

伪代码如下所示:

public int differentFields(Foo foo1, Foo foo2) {
    int differentFields = 0;
   for all fields of foo1 and foo2:
       if foo1.field[i] != foo2.field[i]
           differentFields++;

   return differentFields;
}
字段具有相同的名称,因为我要比较同一类的对象

我不能使用标准的equals来实现这一点,因为Foo有很多字段,我必须编写太多if语句


如何使用反射来实现这一点?

如评论中所述,使用反射来获取所有类成员是一个坏主意。这将解决您的需求:

public <T> int countDiff(T t1, T t2) throws Exception {
    int diffCount = 0;
    Class<? extends Object> tClass = t1.getClass();
    for (Field field : tClass.getDeclaredFields()) {
        field.setAccessible(true);
        Object value1 = field.get(t1);
        Object value2 = field.get(t2);
        if (!isEqual(value1, value2)) {
            diffCount++;
        }
    }
    return diffCount;
}

private boolean isEqual(Object v1, Object v2) {
    return (v1 == null && v2 == null) || (v1 != null && v1.equals(v2));
}
public int countDiff(t1,t2)引发异常{
int diffCount=0;

类如评论中所述,使用反射获取所有类成员是一个坏主意。这应该解决您的要求:

public <T> int countDiff(T t1, T t2) throws Exception {
    int diffCount = 0;
    Class<? extends Object> tClass = t1.getClass();
    for (Field field : tClass.getDeclaredFields()) {
        field.setAccessible(true);
        Object value1 = field.get(t1);
        Object value2 = field.get(t2);
        if (!isEqual(value1, value2)) {
            diffCount++;
        }
    }
    return diffCount;
}

private boolean isEqual(Object v1, Object v2) {
    return (v1 == null && v2 == null) || (v1 != null && v1.equals(v2));
}
public int countDiff(t1,t2)引发异常{
int diffCount=0;


类为什么不在类中使用standard equals实现?你到底想从中得到什么???我想我们都明白你想要做什么,但我们都同意,如果你希望这样做的唯一原因是不要有几个
if
语句,那么这可能是个坏主意。我们在这里讨论多少字段?怎么可能今天和明天有不同数量的字段?您想使用此方法作为不同类的相等替换,还是作为“未来证明”永不再接触相等实现?如果“明天”呢其中一个属性不相关,例如,某个内部缓存变量?因为您希望比较同一类的实例,所以这里不需要反射。您可以直接访问所有字段。这只是因为您可以编写循环(需要更少的语句)这并不自动意味着它是最好的解决方案。而且根本没有冗余!为什么不在类中使用standard equals实现?你到底想得到什么?我想我们都理解你想要做什么,但我们都同意,如果你想要这样做的唯一原因是没有fe,那么这可能是个坏主意w
if
语句。我们在这里讨论的字段有多少?今天和明天的字段数量如何不同?您想将此方法用作不同类的相等替换,还是作为“未来证明”永不再涉及相等实现?如果“明天”呢其中一个属性不相关,例如,某个内部缓存变量?因为您希望比较同一类的实例,所以这里不需要反射。您可以直接访问所有字段。这只是因为您可以编写循环(需要更少的语句)并不自动意味着它是最好的解决方案。而且根本没有冗余!为什么你认为这是个坏主意?使用反射并不常见。如果需要,你应该重新考虑你的设计(或者在你的情况下重新考虑需求).我在一些测试类中使用了反射,但在生产类中从未使用过…当你有像
getsomething这样的方法时,使用getter的方法会变得难看,比如通过执行完整的complexCalculation
。此外,一些getter实际上是从
is
开始的(对于布尔型)@tobias_k谢谢,
isGetter
已调整。你是对的,但我认为如果getter进行一些昂贵的计算,这是一个糟糕的设计。这个答案很好地说明了根本没有办法降低复杂性。这将要付出某种代价。总是。你为什么认为这是个坏主意?使用反射并不常见。如果你需要重新考虑你的设计(或者在你的例子中是需求)。我在一些测试类中使用反射,但从来没有在生产中使用过……当你有像
getsomething这样的方法时,使用getter的方法会变得丑陋,因为你需要执行完整的complexCalculation
。此外,一些getter实际上是从
is
开始的(对于布尔型)@tobias_k谢谢,
isGetter
已调整。你是对的,但我认为如果getter进行一些昂贵的计算,这是一个糟糕的设计。这个答案很好地说明,绝对没有办法降低复杂性。这将要付出某种代价。永远如此。