简体   繁体   English

Java中的致命异常处理

[英]Fatal exception handling in Java

I am creating a basic math parser with Java and doing this is revealing my shallow understanding of Java exception handling. 我正在用Java创建一个基本的数学解析器,这样做揭示了我对Java异常处理的浅薄理解。

when I have this input: 当我有这个输入:

String mathExpression = "(3+5";

and I subsequently call: 然后我打电话给:

throw new MissingRightParenException();

the IDE forces me to surround with a try/catch like so: IDE强制我用try / catch包围,如下所示:

             try {
                    throw new MissingRightParenException();
                } catch (MissingRightParenException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();

                }

however, in order to force this to be a fatal exception, it looks like I have to add my own code to call System.exit() , like so: 但是,为了强制这是一个致命的异常,看起来我必须添加自己的代码来调用System.exit() ,如下所示:

             try {
                    throw new MissingRightParenException();
                } catch (MissingRightParenException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                    System.exit(0);
                }

I am not sure I understand the syntax behind all of this, especially why I have to use a try/catch block around throwing an exception. 我不确定我是否理解所有这些背后的语法,特别是为什么我必须使用try / catch块来抛出异常。

what is the rhyme and reason behind this? 这背后的押韵和原因是什么?

Instead of throwing the exception, I could do this instead: 而不是抛出异常,我可以这样做:

new MissingRightParenException();

instead of calling 而不是打电话

throw new MissingRightParenException();

so I guess my question is - if this is a fatal exception, what is the best way to make it truly fatal while giving the user the best feedback? 所以我想我的问题是 - 如果这是一个致命的例外,那么在给用户提供最佳反馈的同时让它真正致命的最佳方法是什么?

If you want to have a checked exception that you have to catch - but not right away - then you can define throws MissingRightParenException in the signature of your methods. 如果你想要一个必须捕获的检查异常 - 但不是马上 - 那么你可以在方法的签名中定义throws MissingRightParenException

class MissingRightParenException extends CalculationException {
    ...
}

class CalculationException extends Exception {
    ...
}

class MyClass {

    int myMathRelatedMethod(String calculation) throws CalculationException {
        ...
        if (somethingWrong) {
            throw new MissingRightParenException("Missing right paren for left paren at location: " + location);
        }
        ...
    }

    public static void main(String ... args) {        
        ...
        try {
            myMathRelatedMethod(args[0]);
        } catch (CalculationException e) {
            // stack trace not needed maybe
            System.err.println(e.getMessage());
        }
        ...
    }
}

You can also define it as the cause of a RuntimeException but that doesn't seem a good match for your current problem. 您也可以将其定义为RuntimeException原因 ,但这似乎不适合您当前的问题。

try {
     ...
     throw new MissingRightParenException();
     ...
} catch (MissingRightParenException e) {
     // IllegalStateException extends (IS_A) RuntimeException
     throw new IllegalStateException("This should never happen", e);
}

If your MissingRightParenException class extends RuntimeException then you don't have to catch it. 如果您的MissingRightParenException类扩展了RuntimeException那么您不必捕获它。 The message will fall through all methods where it (or it's parent classes such as Throwable , Exception and RuntimeException ) is not explicitly caught. 该消息将落在所有方法中(或者它的父类如ThrowableExceptionRuntimeException )未被显式捕获。 You should however not use RuntimeException s for input related errors. 但是,您不应将RuntimeException用于与输入相关的错误。

Usually the user will get the stack trace or at least the error message, although that depends of course or the error handling further down the line. 通常,用户将获得堆栈跟踪或至少是错误消息,尽管这当然取决于线路上的错误处理。 Note that even main does not have to handle exceptions. 请注意,即使main也不必处理异常。 You can just specify throws Exception for the main method to let the console receive the stack traces. 您可以为main方法指定throws Exception ,让控制台接收堆栈跟踪。

So in the end: use throws in the signature of your methods instead of catching exceptions before you want to handle them. 所以最后:在你想要处理它们之前,使用throws方法的签名而不是捕获异常。

Assuming that your exception is currently a subclass of Exception, which is a Checked Exception, you need to handle in a try catch. 假设您的异常当前是Exception的子类,这是一个Checked Exception,您需要在try catch中处理。 If you can make your exception a RunTimeException, you no longer need to do the try-catch stuffs. 如果你可以使你的异常成为RunTimeException,你不再需要做try-catch的东西。

what is the best way to make it truly fatal while giving the user the best feedback? 在为用户提供最佳反馈的同时,让它真正致命的最佳方法是什么?

Personally, I don't think a missing parenthesis should be a Fatal exception. 就个人而言,我认为缺少的括号应该是致命的例外。 The user should have the possibility to re-try. 用户应该有可能重新尝试。

However, if you really want to know, It is not possible with java to create a custom fatal exception as fatal exception means something went wrong on the system/jvm, not on the program itself. 但是,如果你真的想知道,用java创建自定义致命异常是不可能的,因为致命异常意味着系统/ jvm出错了,而不是程序本身。 Still, you should change System.exit(0) to System.exit(1) or anything not equal to 0 as a program exiting with 0 as error code mean everything went right which is not the definition of an exception. 仍然,您应该将System.exit(0)更改为System.exit(1)或任何不等于0的程序作为退出0的程序,因为错误代码表示一切正常,这不是异常的定义。

I am not sure I understand the syntax behind all of this 我不确定我理解所有这些背后的语法

Basically what you do here is throw an exception so you have two choices, either catch it or re-throw it but anyway it will have to be caught somewhere. 基本上你在这里做的是抛出一个异常,所以你有两个选择,要么抓住它,要么重新抛出它,但无论如何它必须被捕获到某个地方。 Then in the catch you simply end the program returning an error code meaning that something failed System.exit(1) 然后在catch你只是结束程序返回一个错误代码,意味着某些东西失败了System.exit(1)

See this Difference in System. 在系统中看到这种差异。 exit(0) , System.exit(-1), System.exit(1 ) in Java for a better understanding of error code. Java中的exit(0),System.exit(-1),System.exit(1),以便更好地理解错误代码。

If MissingRightParenException is a checked exception (that seems to be the case, otherwise your IDE wouldn't be "nagging") then either you have to wrap it inside a try ... catch block or declare it via a throws clause in the method definition. 如果MissingRightParenException是一个已检查的异常(似乎是这种情况,否则你的IDE不会“唠叨”),那么要么必须将它包装在try ... catch块中,要么通过方法中的throws子句声明它定义。 The latter allows you to "bubble up" the exception and catch in the caller of your method throwing the MissingRightParenException exception. 后者允许你“冒泡”异常并捕获抛出MissingRightParenException异常的方法的调用者。

Did you think about a throws clause? 你有没有想过throws条款?

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

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