为什么我不能比较Exception对象的相等性?

时间:2014-07-06 14:37:55

标签: java

SSCCE:

import java.util.Objects;
public class FooMain {

    private static Exception foo() {
        try {
            throw new Exception();
        } catch (Exception e) {
            return e;
        }
    }


    public static void main(String args[]) {
        final int N = 2;
        Exception es[] = new Exception[N];
        for (int i = 0 ; i < N ; i++)
            es[i] = foo();
        System.out.printf("Exceptions are equal? %b\n", Objects.equals(es[0], es[1]));
        for (int i = 0 ; i < N ; i++) {
            System.out.printf("follows exception %d:\n", i);
            es[i].printStackTrace();
        }
    }
}

以上输出:

 [java] Exceptions are equal? false
 [java] follows exception 0:
 [java] follows exception 1:
 [java] java.lang.Exception
 [java]     at FooMain.foo(FooMain.java:6)
 [java]     at FooMain.main(FooMain.java:17)
 [java] java.lang.Exception
 [java]     at FooMain.foo(FooMain.java:6)
 [java]     at FooMain.main(FooMain.java:17)

3 个答案:

答案 0 :(得分:4)

异常类从equals()继承其Object方法,并且不会覆盖它。您每次都创建新的Exception实例,它们是内存中的不同对象。即使它们的堆栈跟踪相同,它们在内存中仍然具有不同的对象分配,并且使用默认的equals()方法,它们是不同的。

但是,您可以定义自定义异常类并覆盖equals()

答案 1 :(得分:1)

您实际上是在比较它们,但是:

es[0] and es[1] are not the same object

来自Object文档:

类Object的equals方法实现了对象上最具辨别力的等价关系;也就是说,对于任何非空引用值x和y,当且仅当x和y引用同一对象时,此方法才返回true(x == y的值为true)。

您可以通过哈希码对它们进行比较:

Integer.toHexString(System.identityHashCode(es[0])) == Integer.toHexString(System.identityHashCode(es[1]))

然而他们不会成为同一个对象。

我认为你想要比较类,所以这应该有效:

es[0].getClass().equals(es[1].getClass()) 

答案 2 :(得分:0)

异常类没有自己的equals方法实现。所以,它只是检查参考变量。由于创建了两个不同的异常对象,因此引用了不同的引用变量,因此它将equals显示为false。

要详细了解它是如何工作的,请尝试以下操作,有一个静态异常(不确定用例,只是为了理解它失败的原因)

private static Exception myStaticException = new Exception();

private static Exception foo() {
    try {
        throw myStaticException;
    } catch (Exception e) {
        return e;
    }
}

...