关于java:throw和throws Exception有什么区别? 为什么“投掷”不需要接球/最终挡住?

What is the difference between throw and throws Exception? And why does “throws” not require a catch/finally block?

以下代码段让我有些困惑。

1
2
3
4
5
6
7
8
9
10
11
12
try {

public static void showMyName(String str) throws IOException
  {
      if(str.equals("What is your Name?"))
            throw new IOException;
  }

 }catch(IOException e)
   {
      System.out.println ("Exception occurs , catch block called")
   }

现在,我的问题是引发IOException和引发新IOException有什么区别?

为什么我们不要求使用catch,最后阻止抛出IOException?

抛出异常是如何处理异常的。?


生成Exception时,有两种处理方法。

  • 处理异常-这使用catch
  • 声明异常-这使用了throws
  • 因此,通过catchthrows处理已经生成的异常。

    另一方面,在"生成"异常时使用throw

    通常,在实例化Exception对象或将已生成的异常级联到调用方时使用throw关键字。

    例如,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    public void doSomething(String name) throws SomeException { // Exception declared
        if( name == null ){ // cause of the exception
            throw new SomeException(); // actual NEW exception object instantiated and thrown
        }
        // Do something here
        .
        .
        .
    }

    在调用方法中,

    1
    2
    3
    4
    5
    6
    7
    public static void main(String[] args) throws SomeException{ // Need to declare exception because you're"throwing" it from inside this method.
        try { // try doing some thing that may possibly fail
            doSomething(name);
        } catch (SomeException e){
            throw e;// throw the exception object generated in doSomething()
        }
    }

    或者,您可以在catch块中"处理"异常:

    1
    2
    3
    4
    5
    6
    7
    public static void main(String[] args) { // No need to declare exception
        try { // try doing some thing that may possibly fail
            doSomething(name);
        } catch (SomeException e){
            System.out.println("Exception occurred" + e.getMessage()); // Handle the exception by notifying the user.
        }
    }

    希望这可以帮助。

    附录-异常处理词汇表

    • try-用于调用可能导致异常或使用文件/流/网络/数据库连接等资源的代码。
    • catch-在try块之后立即用于"处理"或"引发"异常。如果使用finally,则为可选。
    • finally-在trycatch块之后立即使用。可选的。用于执行"必须"执行的代码。 finally块中的代码始终被执行-即使trycatch具有return语句。
    • throw-用于通过调用方法"推送"或"级联"异常。始终在方法内部使用。
    • throws-用来"声明"如果出现问题,该方法将引发异常。始终用作方法签名的一部分。

    补充阅读

    这是一篇详尽的文章,可帮助您了解Java中的try-catch-finally语义。

    更新资料

    为了回答您的其他问题,

    Why don't we require to use catch , finally block for throws
    IOException ?

    catchthrows视为互斥的构造。 (这并不总是正确的,但对于您的理解,最好从这种想法开始。)

    您声明一个throws IOException方法。这段代码是在声明方法的地方编写的。而且,从语法上讲,您不能在try块中放置方法声明。

    How does throws is handle the exception. ?

    就像我之前提到的,在异常处理期间使用catchfinallythrows仅用于将异常级联回调用方。


    throws关键字表示此方法将引发必须在更高级别处理的所有Exception。

    public static void showMyName(String str) throws IOException

    如果另一个方法调用此方法,则它必须捕获此异常或将其抛出一次(通过在其签名中键入throws)。

    捕获异常还是继续抛出异常,取决于您的业务逻辑。


    第一个最大的不同是投掷可以抛出异常,就像您在河中投掷石块一样,
    并抛出状态,该方法有机会抛出异常,但也可能不会...并且这就是为什么throws不需要try catch的原因,因为它已经声明它已经抛出了某种异常。


    您几乎是正确的。除了一件事,我会稍作提及。

    throws和名称和参数一样,也是方法API的一部分。客户知道如果他们调用该方法,就需要处理该异常-通过简单地将其抛出或捕获并处理该异常(实际上可能需要引发另一个包装原始异常的异常)。抛出是在编译时解决的。

    throw是让运行时知道发生了什么不好的事情的实际行为-实际上,我们担心的异常情况已经发生。因此,它需要在运行时处理。

    但是当您说"如果方法中存在throw语句时,应该总是出现方法签名中的throws",您就不太对劲了。这通常是正确的,但并非总是如此。我还可以调用另一个在我的方法中引发异常的方法,如果我没有捕获到该异常,则我的方法需要抛出该异常。在那种情况下,我没有明确抛出相同的异常。

    最后一点是,仅当异常是已检查的异常时才需要在throws中声明一个异常-这意味着它来自RuntimeException的Exception类层次结构的另一侧。常见的检查异常是IOException和SQLException。如果您自己不处理,则必须在方法签名的throws部分中列出已检查的异常。子类RuntimeException的任何子类(如示例中的NoSuchElementException以及讨厌的NullPointerException子类)都是未经检查的异常,无需捕获或引发任何异常。

    通常,将检查异常应用于可恢复的问题(客户端知道发生了什么,并且可以妥善处理问题并继续进行),而对于灾难性问题使用非检查异常(例如无法连接至数据库)。

    如果您可以克服所有AOP问题,那么这将是有关如何有效使用检查和未检查异常的精彩讨论。


    throw new IOException表示您遇到了一些错误情况,并决定通过引发异常来中断程序流。

    如果该异常是已检查的异常(即不是Error或RuntimeException),则必须在catch块中捕获该异常,或在方法的签名中声明该方法将抛出该异常(或该异常的超类) )。这就是throws IOException的含义。