为什么Exception
类(如RuntimeException)没有实现equals()
方法?
例如,此代码的output为false
:
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
final RuntimeException e1 = new RuntimeException("e");
final RuntimeException e2 = new RuntimeException("e");
System.out.println(e1.equals(e2));
}
}
是否有理由没有实现equals()
?在我看来它会非常有用。
编辑:让我扩展这个问题,因为似乎大多数人认为equals()
实施没有用。
我想知道,为什么异常应该与普通对象区别对待,只有在相同的实例中才匹配。它是否没有足够的信息来与其他对象进行比较。例如,我假设存储调用堆栈的底层StackTraceElement已经实现了equals
方法。
Exceptions定义中是否有某些内容阻止他们根据属性实现equals方法?
答案 0 :(得分:2)
好Exception
是普通的类实例。例外可以维持一个状态。
例如,可以声称在具有特定消息的特定行处抛出的异常不等于在下一行抛出的异常。
即使错误与同一个调用堆栈在同一行上抛出但程序运行不同,也可以说异常不一样......例如,第一个程序可以调用:
java -jar program.jar "arg1" & java -jar program.jar "arg2"
程序有不同的pid
,被抛出不同的时间戳,......
但是,您可以使用继承(对于您自己定义的equals
)自己实现Exception
方法:
public class WeirdException extends Exception {
@Override
public boolean equals (Object obj) {
return (obj instanceof WeirdException);
}
}
毕竟,堆栈跟踪只在构造时“存储”在Exception
中,完全有效的java程序如下:
public class MyClass {
public static void main(String args[]){
Exception ex = new IndexOutOfBoundsException();
ex.printStackTrace(System.out);
}
}
结果是:
java.lang.IndexOutOfBoundsException
at MyClass.main(MyClass.java:15)
换句话说,throw
与Exception
没什么关系。 throw
仅仅意味着“替代return
”。它与存储堆栈跟踪无关,...
答案 1 :(得分:2)
请注意,虽然Exception
没有覆盖equals
,但它确实有一个实现,一个继承自Object
的实现,它比较了身份。
对于大多数情况,您可以实现异常比较器,例如仅记录第一次出现,或者与模板进行比较,尽管我认为在这种情况下堆栈跟踪不具有可比性。如果要支持多于基本字段,则必须为某些异常类定义特定的比较器。
异常不太容易产生价值语义。如果他们有,你会怎么做,将它们用作哈希表键?在这种情况下,您可以实现一个equals
和hashCode
表现得像这样的包装类。
答案 2 :(得分:2)
有一个简单的解释:Exception
的两个不同实例在任何意义上都不相同。
异常平等的含义是什么?如果两个对象相等,则它们在某种程度上在语义上是同一的。但是Exception
的两个实例在语义上始终不同 - 要么在另一个地方发生异常(即,堆栈跟踪不同),要么很可能在另一个时间,即在不同情况下发生。
Exception
s的两个不同实例永远不应该相等,只是因为它们不能代表同样的事情。