等于方法不适用于 Throwable

Equals method not working well with Throwable

我有一些外部提供的回调 运行。因为它们可以包含任何东西,所以我宁愿冒险抓住 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 方法总是 returns 错误。查看此方法生成的输出:

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 不会覆盖 Objectequals,因此 error.equals(lastError) 的行为与 error == lastError.

相同

也许你比较 类 :

就足够了
error.getClass().equals(lastError.getClass())

Throwable 不会 覆盖 equals(),问题就出在这里你的 ErrorLastError 实例可能是 2具有相同值

的不同 Throwable 个实例

equals() 不起作用,因为它只比较实例。如果你两次抛出 "same" 异常,这会给你两个实例,并且 Object.equals() returns false

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

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

另外 Throwable 也会捕获不可恢复的 Errors,您可能不想要这些。该代码应该适用于 Exception 甚至 RuntimeException,具体取决于您的设计工作方式。