Java Equals方法不适用于可丢弃的

Java Equals方法不适用于可丢弃的,java,error-handling,equals,Java,Error Handling,Equals,我有一些外部提供的回调要运行。因为它们可以包含任何内容,所以我更愿意冒险捕捉它们上的Throwable,从而从任何可恢复的错误中恢复 回调执行的某些阶段允许抛出错误,除非错误在一行中重复两次。在这种情况下,它们被标记为无效,除非用户手动启动它们,否则无法再运行 这是处理以下问题的方法: /** * Sets whether the bot is disabled due to error or not. If error has occured during * getWind

我有一些外部提供的回调要运行。因为它们可以包含任何内容,所以我更愿意冒险捕捉它们上的
Throwable
,从而从任何可恢复的错误中恢复

回调执行的某些阶段允许抛出错误,除非错误在一行中重复两次。在这种情况下,它们被标记为无效,除非用户手动启动它们,否则无法再运行

这是处理以下问题的方法:

  /**
   * Sets whether the bot is disabled due to error or not. If error has occured during 
   * getWindow, the bot will be disabled immediatelly. If the error occured during canRun() or run()
   * the bot will only be disabled if the error is repetitive.
   * @param error error that occured
   * @param phase phase of execution in which the error occured
   * @return true if this error is not significant enough to cancel this bot
   */
  public boolean continueOnError(Throwable error, ExecutionPhase phase) {
    System.err.println("Error "+error+" caught in robot "+this.getClass().getName());
    System.err.println("Last: "+lastError+((error.equals(lastError)?" which is the same as last":" which is defferent than last")));
    if(phase == ExecutionPhase.GET_WINDOW || (error.equals(lastError) && phase==errorPhase)) {
      //Remember last
      setLastError(error, phase);
      //If robot state listener is listening, inform it about this event
      if(listener!=null)
        listener.disabledByError(error);
      //Disable the robot - on attempt to run, it will throw RobotDisabledException
      return !(errorDisabled = true);
    }
    //Rememeber last
    setLastError(error, phase);
    //The robot can remain running, but next same error will turn it down
    return true;
  }
我知道这是一种原始的方法,但我需要从某个地方开始。此代码的问题在于
Throwable
上的
equals
方法始终返回false。请参见此方法生成的输出:

Error java.lang.Error: TEST ERROR caught in robot cz.autoclient.robots.LaunchBot
Last: java.lang.Error: TEST ERROR which is defferent than last
Error java.lang.Error: TEST ERROR caught in robot cz.autoclient.robots.LaunchBot
Last: java.lang.Error: TEST ERROR which is defferent than last
Error java.lang.Error: TEST ERROR caught in robot cz.autoclient.robots.LaunchBot
Last: java.lang.Error: TEST ERROR which is defferent than last
Error java.lang.Error: TEST ERROR caught in robot cz.autoclient.robots.LaunchBot
Last: java.lang.Error: TEST ERROR which is defferent than last

为什么会发生这种情况?

Throwable
不会覆盖
对象的
equals
,因此
error.equals(lastError)
的行为与
error==lastError
相同

也许你比较一下这些课程就足够了:

error.getClass().equals(lastError.getClass())

Throwable
不会覆盖
equals()
,问题在于您的
Error
LastError
实例可能是两个不同的
Throwable
实例,它们具有相同的值

equals()
因为它只比较实例,所以不起作用。如果两次抛出“相同”异常,则会得到两个实例,
Object.equals()
为此返回false

Java中没有完美的方法来检查两个异常是否相同(例如,它们可能包含时间戳)

更好的方法可能是记住导致问题的组件,并在它开始抛出太多错误时禁用它(无论是哪一个错误或错误是否重复)


另外,
Throwable
还捕获您可能不想要的不可恢复的
错误。代码应该在
异常
上工作,或者甚至可能在
运行时异常
上工作,这取决于您的设计工作方式。

我假设
阶段
是一个
枚举
。@Boristeider是的。所以我想我必须自己想一想。事实上,怎么会呢?@Boristespider比较所有属性是一个100%确定的方法。@TomášZato:不,不是。@TomášZato所以从不同地方抛出相同消息的异常是不同的?这可能会让一些人感到惊讶。反之,其他人会感到惊讶。我认为,单独抛出的两个异常应该总是不同的,因此
=
最有意义。正如我所说,
可丢弃的
包括不可恢复的错误,但并非所有可丢弃的
都是不可恢复的。如果错误是不可恢复的,那么应用程序无论如何都会下地狱,所以我为什么要在意呢。我不处理任何可能丢失的数据。我提到了这一点,以确保您(以及其他可能阅读此问题的人)知道这一事实。@TomášZato
Throwable
Error
Exception
的父类。说出希望从中恢复的
错误。从不
catch-Throwable
和从不
Throwable
-此类不应出现在代码中的任何位置。曾经。@Boristeider反射中抛出的这种方法错误实际上是无害的。从理论上讲,它甚至可能发生在我的代码思想的某一部分,在它被捕获和处理的特定位置。