简体   繁体   English

Java 内部的异常处理是如何工作的?

[英]How does exception handling work internally in Java?

try 
{
}
catch(ExceptionType name)
{
}

One thing that I'm particularly unable to understand is the argument of Catch Block.我特别无法理解的一件事是 Catch Block 的论点。 We write " catch(ExceptionType name) " What exactly is " name " though?我们写“ catch(ExceptionType name) ”“ name ”到底是什么? If " ExceptionType " is class, shouldn't " name " be reference to an object?如果“ ExceptionType ”是类,“ name ”不应该是对对象的引用吗? Even if it is a reference, since we haven't created any object, what exactly does it contain?即使是引用,既然我们还没有创建任何对象,那么它究竟包含什么?

Now I have come up with this theory regarding Exception Handling - please correct me I'm getting it wrong.现在我想出了这个关于异常处理的理论 - 请纠正我,我弄错了。

CASE 1 - SUPPOSING NO TRY, CATCH BLOCK EXISTS - If an error occurs, the exception handler automatically generates an exception object[based on exception's class] and hands it over to the JVM and then JVM then returns the function or crashing error to be displayed at the run-time CASE 1 - SUPPOSING NO TRY, CATCH BLOCK EXISTS - 如果发生错误,异常处理程序会自动生成一个异常对象[基于异常的类]并将其交给JVM,然后JVM返回要显示的函数或崩溃错误在运行时

CASE 2 - IF PROGRAMMER HAS WRITTEN A TRY CATCH BLOCK - If an error occurs, the exception handler generates an exception object[based on exception's class] and then instead of going to the JVM, it will first look into the catch block and try to match the reference variable to the exception object.情况 2 - 如果程序员已经写了一个 TRY CATCH 块- 如果发生错误,异常处理程序会生成一个异常对象[基于异常的类],然后它不会去 JVM,而是首先查看 catch 块并尝试将引用变量与异常对象匹配。 If the match happens, exception handler hands that object to the catch block reference and then programmer can return the function of his or her choice.如果匹配发生,异常处理程序将该对象交给 catch 块引用,然后程序员可以返回他或她选择的函数。 However, if the match does not happen, exception handler will hand that exception object back to the JVM.但是,如果匹配没有发生,异常处理程序会将该异常对象交还给 JVM。

Is this how Exception Handling work?这是异常处理的工作方式吗?

What exactly is " name " though? 名字”究竟是什么?

name is like a local variable , that is assigned the exception that was thrown. name就像一个局部变量,它被分配了抛出的异常。 Or you can think of it as a method parameter.或者您可以将其视为方法参数。

If " ExceptionType " is class, shouldn't "name" be reference to an object?如果“ ExceptionType ”是类,“名称”不应该是对对象的引用吗?

Both are: ExceptionType is a class, and name is an object reference.两者都是: ExceptionType是一个类,而name是一个对象引用。

we haven't created any object, what exactly does it contain?我们还没有创建任何对象,它到底包含什么?

Whatever logic that threw the exception, created it using the new operator, which is why the throw statement is almost always immediately followed by the new operator, eg throw new IllegalArgumentException() .无论抛出异常的逻辑如何,都使用new运算符创建它,这就是为什么throw语句几乎总是紧跟在new运算符之后,例如throw new IllegalArgumentException()

If it's a built-in exception (like NullPointerException , StackOverflowError , ArrayIndexOutOfBoundsException , etc.), the the JVM runtime created the exception.如果是内置异常(如NullPointerExceptionStackOverflowErrorArrayIndexOutOfBoundsException等),则 JVM 运行时会创建异常。

CASE 1 - SUPPOSING NO TRY, CATCH BLOCK EXISTS案例 1 - 假设不尝试,存在捕获块
CASE 2 - IF PROGRAMMER HAS WRITTEN A TRY CATCH BLOCK案例 2 - 如果程序员写了一个 try catch 块
If an error occurs, the exception handler automatically generates an exception object ...如果发生错误,异常处理程序会自动生成一个异常对象...

Your terminology is off: An "exception handler" is code that handles a thrown exception.您的术语是错误的:“异常处理程序”是处理抛出异常的代码。 See eg UncaughtExceptionHandler .参见例如UncaughtExceptionHandler

If an error occurs, an exception is created and thrown by the JVM runtime, regardless of whether or not there is a try-catch statement.如果发生错误,JVM 运行时会创建并抛出异常,无论是否存在try-catch语句。

From there on, the handling of the exception is the same, regardless of whether the exception was thrown by the system, or us a user-defined exception thrown by the throw statement.从那以后,异常的处理都是一样的,不管异常是系统抛出的,还是我们自定义的throw语句抛出的异常。

Let me explain How JVM handles an Exception?让我解释一下JVM 如何处理异常? Whenever inside a method, if an exception has occurred, the method creates an Object known as Exception Object and hands it off to the run-time system(JVM).无论何时在方法内部,如果发生异常,该方法都会创建一个称为异常对象的对象,并将其交给运行时系统(JVM)。 This exception object contains the details of that particular exception and the current state of the program where an exception has occurred.此异常对象包含该特定异常的详细信息以及发生异常的程序的当前状态。 Creating the Exception Object and handling it to the run-time system is called throwing an Exception .创建异常对象并将其处理到运行时系统称为抛出异常 There might be a list of the methods that had been called to get to the method where an exception has occurred.可能有一个被调用的方法列表,以获取发生异常的方法。 This ordered list of the methods is called Call Stack .这个有序的方法列表称为调用堆栈 Now the following procedure will happen.现在将发生以下过​​程。

  • The run-time system searches the call stack to find the method that contains a block of code that can handle the occurred exception.运行时系统搜索调用堆栈以查找包含可以处理发生的异常的代码块的方法。 The block of the code is called an Exception handler.代码块称为异常处理程序。
  • The run-time system starts searching from the method in which exception occurred, proceeds through call stack in the reverse order in which methods were called.运行时系统从发生异常的方法开始搜索,按照与调用方法相反的顺序遍历调用堆栈。
  • If it finds an appropriate handler then it passes the occurred exception to it.如果它找到合适的处理程序,则将发生的异常传递给它。 Appropriate handler means the type of the exception object thrown matches the type of the exception object it can handle.适当的处理程序意味着抛出的异常对象的类型与其可以处理的异常对象的类型相匹配。
  • If the run-time system searches all the methods on the call stack and couldn't have found the appropriate handler then the run-time system handover the Exception Object to the default exception handler, which is part of the run-time system.如果运行时系统搜索调用堆栈上的所有方法并且找不到合适的处理程序,则运行时系统将异常对象移交给默认的异常处理程序,它是运行时系统的一部分。 This handler prints the exception information in the following format and terminates the program abnormally.此处理程序按以下格式打印异常信息并异常终止程序。

Now how flow control work in try catch finally block in java现在流控制如何在 try catch finally 块中工作在 java 中

  1. Control flow in try-catch clause OR try-catch-finally clause: a. try-catch 子句或 try-catch-finally 子句中的控制流程: Case 1: Exception occurs in a try block and is handled in the catch block.情况 1:异常发生在 try 块中并在 catch 块中处理。 b.Case 2: Exception that occurs in try-block is not handled in the catch block.情况 2: try-block 中发生的异常不在 catch 块中处理。 c. C。 Case 3: Exception doesn't occur in try-block情况 3: try-block 中没有发生异常

  2. try-finally clause a. try-finally 子句a. Case 1: Exception occurs in the try block.情况 1: try 块中发生异常。 b.Case 2: Exception doesn't occur in try-block.情况 2: try-block 中没有发生异常。

For more information regarding the flow control work in the try-catch-finally block you can refer to this link有关 try-catch-finally 块中的流量控制工作的更多信息,您可以参考此链接

If ExceptionType is class, shouldn't name be reference to an object?如果ExceptionType是类, name不应该是对对象的引用吗? Even if it is a reference, since we haven't created any object, what exactly does it contain?即使是引用,既然我们还没有创建任何对象,那么它究竟包含什么?

The simple answer to your question / misunderstanding is that catching an exception does NOT create an exception object.对您的问题/误解的简单回答是捕获异常不会创建异常对象。 Rather, the exception object was created earlier .相反,异常对象是更早创建的

When you do this:当你这样做时:

 throw new SomeException("message");

the new is explicitly creating an exception object. new显式地创建了一个异常对象。

When you do this:当你这样做时:

SomeClass foo = null;
foo.someMethod();

the JVM will create a NullPointerException object. JVM 将创建一个NullPointerException对象。

In either case, it will be those objects that are assigned to the variable in the catch clause;无论哪种情况,都将是那些在 catch 子句中分配给变量的对象; name in your example.在您的示例中的name


This also indirectly explains something else.这也间接地说明了一些别的事情。 When you call printStackTrace() on an exception object, it will (apparently) print the stack trace for the point at which the exception was thrown.当您在异常对象上调用printStackTrace()时,它会(显然)打印抛出异常点的堆栈跟踪。

How does it manage this?它是如何管理的?

Well actually, what I said above was slightly incorrect.其实我上面说的有点不对。 What it is actually printing is the stacktrace for the point at which the exception object was created!实际打印的是创建异常对象时的堆栈跟踪 (The two points are usually the same, but not always.) (这两个点通常相同,但并非总是如此。)

What actually happens is that when the exception object is created (by new , by the JVM, or by native code) the constructor for Throwable (the ancestor class of all exception classes) calls a method called fillInStackTrace() .实际发生的是,当异常对象被创建时(通过new 、JVM 或本地代码), Throwable的构造函数(所有异常类的祖先类)调用一个名为fillInStackTrace()的方法。 This in turn calls an internal method that populates an array with the stack frame information for the current call context.这反过来调用一个内部方法,该方法使用当前调用上下文的堆栈帧信息填充数组。

If I fully understood your question, this may be what you're looking for.如果我完全理解你的问题, 可能就是你要找的。 Since Java is an interpreted language, when the JVM finds the correct error while executing the bytecode, it will jump to the bytecode for the block that you wrote in the except block, making a new SomeException() , which is basically an object of information about the error, and passes it as that local variable parameter, in your code ExceptionType name .由于Java是一种解释型语言,当JVM在执行字节码时发现正确的错误,会跳转到你在except块中写的那个块的字节码,生成一个new SomeException() ,基本上是一个信息对象关于错误,并在您的代码ExceptionType name中将其作为该局部变量参数传递。

Referencing your example of no try / catch, it would have to just throw an error, print stack trace, and exit with an error, and no SomeException object is instantiated.参考你的不尝试/捕获的例子,它只需要抛出一个错误,打印堆栈跟踪,并以错误退出,并且没有实例化 SomeException 对象。 Hope I can help.希望我能帮上忙。 Some links that may be of interest are here , here , and maybe here (similar question) .一些可能感兴趣的链接在这里这里,也许这里(类似问题)

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

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