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

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) 

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

但是,您可以定义自定义exception类并重写equals()

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

 es[0] and es[1] are not the same 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()) 

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

要显示有关它的工作原理的更多信息,请尝试以下操作,有一个静态exception(不确定用例,只是为了理解它失败的原因)

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

….