[英]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.如果是内置异常(如
NullPointerException
、 StackOverflowError
、 ArrayIndexOutOfBoundsException
等),则 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.
现在将发生以下过程。
Now how flow control work in try catch finally block in java现在流控制如何在 try catch finally 块中工作在 java 中
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 中没有发生异常
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'tname
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.