当我自己使用参数字符串引发异常时,会发生什么情况?什么时候调用toString方法?

时间:2018-10-27 15:57:01

标签: java exception-handling

我真的很难理解异常处理的工作原理。 为什么最好为我自己的用户定义的异常扩展 Long value1 = fechaVisita.getTimeInMillis(); Long value2 = fechaDesde.getTimeInMillis(); Long visitante = Calendar.getTimeInMillis(); value1 < visitante < value2 类而不是Exception类?

Throwable

try { //some SQL exception } catch(SQLException e) { System.out.println(e); } 在这里实际上代表什么?我知道这是对SQL异常对象的引用,但是它将显示什么?它调用e方法吗?

Edit:当我覆盖toString方法并将其从源代码中完全删除时,得到的输出是非常不同的。请解释为什么?

toString

class MyException extends Throwable {
  private int detail;

  MyException(String msg) {
    super(msg);
  }

  public String toString() {
    return "MyException[" + detail + "]";
  } 
}

2 个答案:

答案 0 :(得分:3)

>为什么最好为我自己的用户定义的异常扩展throwable而不是Exception类?

不是。您已编辑问题以将其反转为:

  

对于我自己的用户定义的异常,为什么最好扩展Exception而不是Throwable类?

通常,例外情况应为Exceptions;线索就是名字。 :-) Throwable也不例外,它是可抛出的。 (也就是说,JDK中的Throwable / Error / Exception / RuntimeException层次结构通常被认为布局不佳。例如,{{1} }及其子类被检查,其子类Throwable被检查,但子类Exception没有被检查,还有另一个RuntimeException子类{{1 }},这也是未经检查的。我相信,这样做是出于历史原因,而不是因为它的设计很棒。)

对于您自己的例外情况:

    如果应该检查,则
  • 扩展Throwable(或Error以外的子类之一)。

  • 如果您的异常应未检查 ,则扩展Exception(或其子类之一)。

  • 非常 的情况下,您编写的代码符合RuntimeException的定义,您可以将其子类或子类之一子类,但我认为我从未见过带有RuntimeException子类的代码库。通常,Error用于JVM级别的错误,例如“内存不足”。

Error
     

e在这里实际代表什么?我知道这是对SQL异常对象的引用...

是的,它是SQLException或其子类的实例。

  

...但是它将显示什么?它调用toString方法吗?

是的,间接地:PrintStream#println(Object)调用String.valueOf(Object),后者在对象上调用Error

  

当我覆盖toString方法并将其从源代码中完全删除时,我得到的输出是非常不同的。请解释为什么?

因为您的try { //some SQL exception} catch(SQLException e) {System.out.println(e);} 的实现方式与toString的{​​{1}}的实现方式不同。您所做的toString也与最初显示的不同(使用字符串连接),尽管并没有太大的区别。无论如何,都使用实例的Throwable

答案 1 :(得分:0)

Throwable是Java语言中所有错误和异常的超类。它有两个直接实现:错误和异常。 错误是一个子类,它指示严重的问题,而合理的应用程序不应尝试抓住这些问题。 异常表示合理的应用程序可能希望捕获的条件。

因此,您不应创建实现Throwable的自定义异常,也不应捕获Throwable,因为这样做还会捕获Error类型,并且不应将Error缓存。

值得一提的是,有一个著名的Exception子类型:RuntimeException。 RuntimeException是未经检查的异常,这意味着您可以抛出它们,而调用方也不必强制捕获它。

多年来,关于使用Exception与RuntimeException的争论非常激烈。 RuntimeException赢得了胜利(有些人仍然会认为当然是相反的),但是在早期,使用Exception被认为是最主要的方法,这就是为什么一些第一个版本的Java API抛出Exception类型,而现代Java API和框架在大多数时候抛出RuntnimeException的原因。

  

e在这里实际代表什么?我知道这是对SQL异常对象的引用,但是它将显示什么?它会调用toString方法吗?

您是正确的,e是SQLException类型的变量的名称,您可以在内部catch块中使用它。并且它确实像添加到System.out.println()中的每个对象一样调用其toString方法。

  

Edit:当我覆盖toString方法以及将其从源代码中完全删除时,我得到的输出是非常不同的。请解释为什么?

在您的示例中,如前所述,您正在扩展Throwable,您不应这样做。文档说:所有扩展Throwable的类都将使用其toString()实现。

  

/ **        *返回此throwable的简短描述。        *结果是以下内容的串联:        *

           *
  • 此对象的类的{@linkplain Class#getName()名称}        *
  • “:”(冒号和空格)        *
  • 调用该对象的{@link #getLocalizedMessage}的结果        * 方法        *
       *如果{@code getLocalizedMessage}返回{@code null},则只需        *返回班级名称。        *        * @返回此throwable的字符串表示形式。        * /       公共字符串toString()

因此,如果您覆盖它,例如您的示例。您不再能获得它的好处,您的toString()方法仅打印您放入其中的内容。