猿问

当我自己用参数字符串抛出异常时究竟会发生什么?什么时候调用 toString 方法?

我真的很难理解异常处理是如何工作的。为什么最好为我自己的用户定义的异常扩展Exception而不是Throwable类?


try {

   //some SQL exception

catch(SQLException e) {

  System.out.println(e);

什么是e真正代表了这里?我知道它是对 SQL 异常对象的引用,但它会打印什么?它会调用toString方法吗?


编辑:当我覆盖该toString方法和从我的源代码中完全删除它时,我得到的输出非常不同。请解释为什么?


class MyException extends Throwable {

  private int detail;


  MyException(String msg) {

    super(msg);

  }


  public String toString() {

    return "MyException[" + detail + "]";

  } 

}

class ExceptionDemo {

  static void compute(int a) throws MyException {  // cant be thrown as throwable 

    System.out.println("Called compute(" + a + ")");

    if(a > 10)

      throw new MyException("MyException class error");

    System.out.println("Normal exit");

  }


  public static void main(String args[]) {

    try {

      compute(1);

      compute(20);

    } catch (MyException e) {

      System.out.println("Caught " + e);

    }

  }

}


蝴蝶刀刀
浏览 149回答 2
2回答

青春有我

Throwable 是 Java 语言中所有错误和异常的超类。它有两个直接的实现:错误和异常。Error 是一个子类,它指示合理的应用程序不应尝试捕获的严重问题。异常表示合理的应用程序可能想要捕获的条件。因此,您不应创建实现 Throwable 的自定义异常,也不应捕获 Throwable,因为这样做也会捕获 Error 类型,并且不应缓存 Error 类型。还值得一提的是,Exception 有一个著名的子类型:RuntimeException。RuntimeException 是未经检查的异常,这意味着您可以抛出它们并且调用者不会被迫捕获它。多年来,关于使用 Exception 与 RuntimeException 的争论一直很激烈。RuntimeException 赢了(当然有些人可能仍然认为相反),但在早期使用 Exception 被认为是王者,这就是为什么第一版本的几个 Java API 抛出 Exception 类型,而现代 Java API 和框架大部分时间都抛出 RuntnimeException。至于e在这里实际上代表什么?我知道它是对 SQL 异常对象的引用,但它会打印什么?它会调用 toString 方法吗?你是对的,e 是 SQLException 类型的变量的名称,你可以在 catch 块中使用它。它确实像每个 Object 在 System.out.println() 中添加时那样调用它的 toString 方法。编辑:当我覆盖 toString 方法和从我的源代码中完全删除它时,我得到的输出非常不同。请解释为什么?在您的示例中,您正在扩展 Throwable,如前所述,您不应该这样做。所有扩展 Throwable 的类都将使用它的 toString() 实现,它的文档说:/** * 返回此 throwable 的简短描述。* 结果是: **此对象的类的{@linkplain Class#getName() name} *“:”(一个冒号和一个空格)*调用此对象的 {@link #getLocalizedMessage} * 方法的结果 ** 如果 {@code getLocalizedMessage} 返回 {@code null},则只返回 * 类名。* * @return 这个 throwable 的字符串表示。*/ 公共字符串 toString()所以,如果你覆盖它,就像在你的例子中一样。您不再获得它的好处,您的 toString() 方法只打印您放入其中的内容。

德玛西亚99

为什么最好为我自己的用户定义的异常扩展 Exception 而不是 Throwable 类?因为一般来说,例外应该是Exceptions; 线索就在名字里。:-)Throwable不是一个例外,它是一个 throwable。(这就是说,Throwable/ Error/ Exception/ RuntimeExceptionJDK中的层次结构通常被视为不良布局。例如,这是奇怪的是,Throwable和它的子类进行检查,其子Exception被选中,但它的子类RuntimeException是没有了,还有这其他Throwable子类,Error,这也是未经检查的。我相信这是出于历史原因,而不是因为它的设计很棒。)对于您自己的例外:如果应该检查您的异常,请扩展Exception(或其子类之一RuntimeException)。RuntimeException如果您的异常应该是unchecked ,请扩展(或其子类之一)。在极不可能的情况下,您正在编写符合 an 定义的代码Error,您可以子类化该类或其子类之一,但我认为我从未见过包含Error子类的代码库。大多数情况下,Error是针对 JVM 级别的错误,例如“内存不足”。try { //some SQL exception} catch(SQLException e) {System.out.println(e);} e在这里实际上代表什么?我知道它是对 SQL 异常对象的引用...是的,它是 SQLException 的实例或其子类。...但它会打印什么?它会调用 toString 方法吗?是的,间接地:PrintStream#println(Object)调用String.valueOf(Object),它调用toString对象。当我覆盖 toString 方法和从我的源代码中完全删除它时,我得到的输出非常不同。请解释为什么?因为您toString的实现方式与Throwable'stoString的实现方式不同。您所做的也println与您最初展示的不同(使用字符串连接),尽管它没有什么大的不同。toString无论如何都会使用您的实例。
随时随地看视频慕课网APP

相关分类

Java
我要回答