Java - 为什么不调用 ArithmeticException class 的 subclass?
Java - Why the subclass of ArithmeticException class is not called?
我想修改 ArithmeticException
输出消息。所以,为此我做了一些实验。我将 ArithmeticException
class 扩展了 ExtenderClass
class。这个问题的重点不仅是找到修改 ArithmeticException
异常消息的解决方案,而且还要说明为什么下面的某些情况按预期工作而有些情况却没有?以下是案例及其输出:
案例一:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
}catch(ArithmeticException e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
I caught: java.lang.ArithmeticException: / by zero
结果:按预期工作正常。
案例二:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
}catch(ExtenderClass e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at MyClass.main(MyClass.java:9)
结果:意味着 throw/catch
没有被触发。为什么 ExtenderClass
没有被解雇?事实上它扩展了 ArithmeticException
class?
案例三:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
throw new ArithmeticException();
}catch(ArithmeticException e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
I caught: java.lang.ArithmeticException: / by zero
结果:按预期工作正常。
案例四:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
throw new ExtenderClass();
}catch(ExtenderClass e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at MyClass.main(MyClass.java:9)
结果:意味着 throw/catch
没有被触发。为什么 ExtenderClass
没有被解雇?事实上它扩展了 ArithmeticException
class?
为什么扩展 ArithmeticException
的 ExtenderClass
class 没有被触发?但是当我直接使用 ArithmeticException
时,它会被触发。
正在审查您的案例:
1) 您按预期引发并捕获了 ArithmeticException
。 ExtenderClass
未使用。
2) ArithmeticException
被抛出并且没有被 您的 代码捕获,因为 ExtenderClass
更具体 比 ArithmeticException
.
3) 您按预期引发并捕获了 ArithmeticException
。注意:执行没有达到你明确抛出 ArithmeticException
.
的地步
4) 你用行 c = a / b
引起了一个 ArithmeticException
并且它没有被 你的 代码捕获,因为 ExtenderClass
是 比 ArithmeticException
更具体 。执行未达到您明确抛出 ExtenderClass
.
的程度
虽然您已将自定义异常声明为 ArithmeticException
的子类,但您无法让 a / b
抛出您的自定义异常。 JLS 指定(整数)除以零将抛出 ArithmeticException
;参见 JLS 15.17.2 第 3 段。
由于抛出的异常是 ArithmeticException
,您将无法将其作为自定义异常捕获。
try {
c = a / b;
} catch (ExtenderClass ex) {
...
}
将捕获 ExtenderClass
和 ExtenderClass
的子类。 ArithmeticException
不是 ExtenderClass
的子类,所以上面的 不会 捕获它。
您创建 ExtenderClass
的原因是...
I want to modify the ArithmeticException
output message.
您最好编写一些特殊情况的代码,以便在打印时用不同的消息替换“/ zero”消息。
或者....
try {
c = a / b;
} catch (ArithmeticException ex) {
thrown new ExtenderClass("Division by zero is cool!, ex);
}
创建 ArithmeticException
的子 class 不会导致在将 int
除以 0 时抛出该子 class 的实例。
将 int
除以 0 将始终抛出基数 ArithmeticException
class.
您的 ExtenderClass
只有在您在代码中明确抛出它时才会被抛出:
try {
c = a / b;
} catch(ArithmeticException e) {
throw new ExtenderClass ();
}
在您明确抛出 ExtenderClass
的唯一情况下(案例 4),该抛出语句永远不会到达,因为前面的语句导致 ArithmeticException
被抛出。
如评论中所述:
try{
c = a / b; // ArithmeticException was thrown at this line
throw new ExtenderClass(); // So this line was not executed
}catch(ExtenderClass e){ // This line will catch ExtenderClass and it's sub class. However, ArithmeticException is super class of ExtenderClass, not it's sub class, so it won't be caught
System.out.println("I caught: " + e);
}
很好的观察。
请看我的解释:
注意:
根据您的代码片段 ArithmeticException
是 SuperClass 和 ExtenderClass
是 子类
In Java catch
块只有在其内部定义的异常与 [= 中抛出的异常相同时才会执行57=]try
块或比 try
块更宽。
解释:
案例一
这里你抛出 ArithmeticException
并用相同的 class 捕获它,所以 catch 块按预期执行。
案例二
在这里,您在第 1 行抛出 ArithmeticException
。 9 c = a / b;
并试图通过它的 subclass 来捕捉,这是不可能的。
所以异常没有在 catch 块中处理。
您应该通过相同或 Broader Exception(Super class).
捕获
案例三
这种情况与情况 2 类似,只是您被 Same Exception(ArithmeticException) 捕获并抛出 ArithmeticException
2 次
try{
c = a / b;
throw new ArithmeticException();
}catch(ArithmeticException e){
System.out.println("I caught: " + e);
}
这一行 throw new ArithmeticException();
不会作为上一行抛出的异常执行。
在第 c = a / b;
行,你抛出 ArithmeticException
并在 catch
块中捕获相同的内容,因此它按预期工作
案例4
在这种情况下,您首先抛出 ArithmeticException
然后 ExtenderClass
因此只会抛出第一个异常并且控制永远不会按照下面的代码转到第二个。
try{
c = a / b;
throw new ExtenderClass();
}catch(ExtenderClass e){
System.out.println("I caught: " + e);
}
在这里你试图通过 Subclass(ExtenderClass
) 捕捉,这是不可能的。所以 catch
块将不会处理异常。
我想修改 ArithmeticException
输出消息。所以,为此我做了一些实验。我将 ArithmeticException
class 扩展了 ExtenderClass
class。这个问题的重点不仅是找到修改 ArithmeticException
异常消息的解决方案,而且还要说明为什么下面的某些情况按预期工作而有些情况却没有?以下是案例及其输出:
案例一:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
}catch(ArithmeticException e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
I caught: java.lang.ArithmeticException: / by zero
结果:按预期工作正常。
案例二:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
}catch(ExtenderClass e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at MyClass.main(MyClass.java:9)
结果:意味着 throw/catch
没有被触发。为什么 ExtenderClass
没有被解雇?事实上它扩展了 ArithmeticException
class?
案例三:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
throw new ArithmeticException();
}catch(ArithmeticException e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
I caught: java.lang.ArithmeticException: / by zero
结果:按预期工作正常。
案例四:
// Both the classes are in the same file 'MyClass.java'
class MyClass{
public static void main(String args[]){
int a,b,c;
a = 1;
b = 0;
try{
c = a / b;
throw new ExtenderClass();
}catch(ExtenderClass e){
System.out.println("I caught: " + e);
}
}
}
class ExtenderClass extends ArithmeticException{
// ...
}
输出:
Exception in thread "main" java.lang.ArithmeticException: / by zero
at MyClass.main(MyClass.java:9)
结果:意味着 throw/catch
没有被触发。为什么 ExtenderClass
没有被解雇?事实上它扩展了 ArithmeticException
class?
为什么扩展 ArithmeticException
的 ExtenderClass
class 没有被触发?但是当我直接使用 ArithmeticException
时,它会被触发。
正在审查您的案例:
1) 您按预期引发并捕获了 ArithmeticException
。 ExtenderClass
未使用。
2) ArithmeticException
被抛出并且没有被 您的 代码捕获,因为 ExtenderClass
更具体 比 ArithmeticException
.
3) 您按预期引发并捕获了 ArithmeticException
。注意:执行没有达到你明确抛出 ArithmeticException
.
4) 你用行 c = a / b
引起了一个 ArithmeticException
并且它没有被 你的 代码捕获,因为 ExtenderClass
是 比 ArithmeticException
更具体 。执行未达到您明确抛出 ExtenderClass
.
虽然您已将自定义异常声明为 ArithmeticException
的子类,但您无法让 a / b
抛出您的自定义异常。 JLS 指定(整数)除以零将抛出 ArithmeticException
;参见 JLS 15.17.2 第 3 段。
由于抛出的异常是 ArithmeticException
,您将无法将其作为自定义异常捕获。
try {
c = a / b;
} catch (ExtenderClass ex) {
...
}
将捕获 ExtenderClass
和 ExtenderClass
的子类。 ArithmeticException
不是 ExtenderClass
的子类,所以上面的 不会 捕获它。
您创建 ExtenderClass
的原因是...
I want to modify the
ArithmeticException
output message.
您最好编写一些特殊情况的代码,以便在打印时用不同的消息替换“/ zero”消息。
或者....
try {
c = a / b;
} catch (ArithmeticException ex) {
thrown new ExtenderClass("Division by zero is cool!, ex);
}
创建 ArithmeticException
的子 class 不会导致在将 int
除以 0 时抛出该子 class 的实例。
将 int
除以 0 将始终抛出基数 ArithmeticException
class.
您的 ExtenderClass
只有在您在代码中明确抛出它时才会被抛出:
try {
c = a / b;
} catch(ArithmeticException e) {
throw new ExtenderClass ();
}
在您明确抛出 ExtenderClass
的唯一情况下(案例 4),该抛出语句永远不会到达,因为前面的语句导致 ArithmeticException
被抛出。
如评论中所述:
try{
c = a / b; // ArithmeticException was thrown at this line
throw new ExtenderClass(); // So this line was not executed
}catch(ExtenderClass e){ // This line will catch ExtenderClass and it's sub class. However, ArithmeticException is super class of ExtenderClass, not it's sub class, so it won't be caught
System.out.println("I caught: " + e);
}
很好的观察。
请看我的解释:
注意:
根据您的代码片段
ArithmeticException
是 SuperClass 和ExtenderClass
是 子类
In Java
catch
块只有在其内部定义的异常与 [= 中抛出的异常相同时才会执行57=]try
块或比try
块更宽。
解释:
案例一
这里你抛出ArithmeticException
并用相同的 class 捕获它,所以 catch 块按预期执行。案例二
在这里,您在第 1 行抛出ArithmeticException
。 9c = a / b;
并试图通过它的 subclass 来捕捉,这是不可能的。
所以异常没有在 catch 块中处理。 您应该通过相同或 Broader Exception(Super class). 捕获
案例三
这种情况与情况 2 类似,只是您被 Same Exception(ArithmeticException) 捕获并抛出ArithmeticException
2 次try{ c = a / b; throw new ArithmeticException(); }catch(ArithmeticException e){ System.out.println("I caught: " + e); }
这一行throw new ArithmeticException();
不会作为上一行抛出的异常执行。 在第c = a / b;
行,你抛出ArithmeticException
并在catch
块中捕获相同的内容,因此它按预期工作案例4
在这种情况下,您首先抛出ArithmeticException
然后ExtenderClass
因此只会抛出第一个异常并且控制永远不会按照下面的代码转到第二个。try{ c = a / b; throw new ExtenderClass(); }catch(ExtenderClass e){ System.out.println("I caught: " + e); }
在这里你试图通过 Subclass(
ExtenderClass
) 捕捉,这是不可能的。所以catch
块将不会处理异常。