简体   繁体   English

异常处理; 试着抓

[英]Exception Handling; Try Catch

Here's my code: 这是我的代码:

class FinallyDemo {
    static void myMethod(int n) throws Exception{
        try {
            switch(n) {
                case 1: 
                    System.out.println("1st case");
                    return;
                case 3: 
                    System.out.println("3rd case");
                    throw new RuntimeException("3!");
                case 4: 
                    System.out.println("4th case");
                    throw new Exception("4!");
                case 2: 
                    System.out.println("2nd case");
            }
        catch (RuntimeException e) {
            System.out.print("RuntimeException: ");
            System.out.println(e.getMessage());
        } finally {
            System.out.println("try-block entered.");
        }
    }

    public static void main(String args[]){
        for (int i=1; i<=4; i++) {
            try {
                FinallyDemo.myMethod(i);
            } catch (Exception e){
                System.out.print("Exception caught: ");
                System.out.println(e.getMessage());
            }
            System.out.println();
        }
    }
}

Now, doesnt it work this way: 现在,它不是这样工作的:

If I have a try and catch block in the method itself then I need not write 如果我在方法本身中有一个try and catch块,那么我不需要写

method_name(int n) throws Exception ? method_name(int n) throws Exception

Doesnt try-catch block in the method that throws exception prevents from writing "throws exception" in the method that throws exception? 引发异常的方法中的try-catch块是否可以防止在引发异常的方法中写入“引发异常”?

In your example, the case 4 throws an exception while in the catch you are just catching the RuntimeException. 在您的示例中,案例4引发了一个异常,而在catch中,您只是在捕获RuntimeException。 Since there is not catch for Exception, your method needs to declare that it throws Exception. 由于没有捕获到Exception,因此您的方法需要声明它抛出Exception。 If you were to add a catch for Exception, you wouldn't need to throw Exception. 如果要为Exception添加一个捕获,则不需要抛出Exception。 This will work. 这将起作用。

static void myMethod(int n) {
    try {
        switch (n) {
            case 1:
                System.out.println("1st case");
                return;
            case 3:
                System.out.println("3rd case");
                throw new RuntimeException("3!");
            case 4:
                System.out.println("4th case");
                throw new Exception("4!");
            case 2:
                System.out.println("2nd case");
        }
    } catch (RuntimeException e) {
        System.out.print("RuntimeException: ");
        System.out.println(e.getMessage());
    } catch (Exception e) {
        System.out.print("Exception: ");
        System.out.println(e.getMessage());
    } 
    finally {
        System.out.println("try-block entered.");
    }
}

You don't need the throws clause if and only if the type of exception being thrown is caught (or if it extends RuntimeException . In your case, you throw an Exception with the statement throw new Exception("4!"); , but you only catch the type RuntimeException . 当且仅当捕获了所抛出的异常类型(或它扩展了RuntimeException时,才不需要throws子句。在您的情况下,您使用语句throw new Exception("4!");抛出了Exception ,但是您只捕获类型RuntimeException

If you add a catch block for Exception , then you will no longer need the throws clause. 如果为Exception添加catch块,则不再需要throws子句。 For example: 例如:

static void myMethod(int n) throws Exception{
    try {
        switch(n) {
        case 1: 
            System.out.println("1st case");
            return;
        case 3: 
            System.out.println("3rd case");
            throw new RuntimeException("3!");
        case 4: 
            System.out.println("4th case");
            throw new Exception("4!");
        case 2: 
            System.out.println("2nd case");
        }
    } catch (RuntimeException e) {
        System.out.print("RuntimeException: ");
        System.out.println(e.getMessage());
    } catch(Exception e) {
        System.out.print("Exception: ");
        System.out.println(e.getMessage());
    } finally {
        System.out.println("try-block entered.");
    }
}

Yes, provided you're catching all exception types that can be thrown by the method. 是的,前提是您要捕获该方法可能引发的所有异常类型。

In your code, you throw an Exception but do not supply a catch block for it (you are only catching RuntimeException ), therefore you must declare your method as throwing Exception 在您的代码中,您抛出Exception但不为其提供catch块(您仅捕获RuntimeException ),因此必须将您的方法声明为throwing Exception

You would need: 您将需要:

 ...
 catch (RuntimeException e) {
     System.out.print("RuntimeException: ");
     System.out.println(e.getMessage());
 } catch (Exception e) {
     System.out.print("Exception: ");
     System.out.println(e.getMessage());
 } finally {
 ...

Doesnt try-catch block in the method that throws exception prevents from writing "throws exception" in the method that throws exception? 引发异常的方法中的try-catch块是否可以防止在引发异常的方法中写入“引发异常”?

No, you can always declare to throw exceptions, even if you do not. 不,您始终可以声明引发异常,即使您不这样做也是如此。

Among other things this is useful to allow subclasses to throw them (because they are not allowed to add additional throw clauses). 除其他外,这对允许子类抛出它们很有用(因为不允许子类添加其他throw子句)。 It also allows you to later change the implementation without changing the exception interface. 它还允许您以后更改实现而不更改异常接口。

Right now are tow types of exceptions 现在是两种例外

  1. Subclasses of Exception. Exception的子类。
  2. Subclasess of RuntimeException RuntimeException子句

The subclasses of Exception are know as checked exception and the compiler ensures that these are managed in try/catch block or through the modifier throws Exception (or subclass) on method. Exception的子类被称为检查异常,编译器确保通过try / catch块或通过修饰符在方法上抛出Exception (或子类)来对它们进行管理。

The subclasess oF RuntimeException are know as unchecked exception and the compile don't require any mechanism for manage it. RuntimeException的子类被称为未经检查的异常,并且编译不需要任何机制来对其进行管理。

Now if you use the modifier throws Exception (or subclass) on a method the compiler will require you manage it with try/catch. 现在,如果在方法上使用修饰符throws Exception (或子类),则编译器将要求您使用try / catch对其进行管理。

Since you throw both a RuntimeException and an Exception in the switch, you either need to catch both or the method needs to throw the Exception so it can be handled in the method calling myMethod 由于在开关中同时抛出RuntimeExceptionException ,因此您要么需要捕获两者,要么方法需要抛出Exception以便可以在调用myMethod的方法中对其进行处理。

To catch both use: 要同时使用:

catch (RuntimeException e) {
        System.out.print("RuntimeException: ");
        System.out.println(e.getMessage());
}catch (Exception e) {
        System.out.print("Exception: ");
        System.out.println(e.getMessage());
}

Make sure the catch of Exception is always last, otherwise it will also catch the RuntimeException since it extends Exception 确保Exception的捕获始终是最后一个,否则它将捕获RuntimeException因为它扩展了Exception

You are handling the exception in TWO ways. 您正在以两种方式处理异常。 Firstly if you extend the directly call the Exception class as you have done when declaring the method 首先,如果像在声明方法时所做的那样扩展直接调用Exception类,

method_name(int n) throws Exception

What this means is that no matter what type of exception occurs in the method it will always be able to catch it, For example if an Arithmetic Exception or a NullPointerException or an ArrayIndexOutOfBoundsException occurs inside the method your above declaration will be able to catch each and every one of them. 这意味着无论方法中发生什么类型的异常,它都将始终能够捕获它,例如,如果方法内部发生算术异常或NullPointerException或ArrayIndexOutOfBoundsException,则上述声明将能够捕获每个异常,并且每个人。 Because of that there is no actual purpose of having the try catch block as well placed inside that method because even RunTimeException is part of the Exception Class hierarchy. 因此,将try catch块放置在该方法中并没有实际目的,因为即使RunTimeException也是Exception Class层次结构的一部分。 Therefore if I understood your question correctly the program will execute and then catch the exception from the catch block, failing which it will catch it from the method declaration. 因此,如果我正确理解了您的问题,程序将执行,然后从catch块中捕获异常,否则,它将从方法声明中捕获该异常。 Hope it answers your query. 希望它能回答您的查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM