Java - 为什么不调用 ArithmeticException 类的子类



我想修改ArithmeticException输出消息。所以,为此我做了一些实验。我把ArithmeticException类扩展ExtenderClass类。这个问题的重点不仅是找到修改ArithmeticException异常消息的解决方案,而且还要说明为什么下面的某些情况按预期工作,而有些情况则不然?以下是这些情况及其输出:

案例1:

// 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

结果:按预期正常工作。


案例2:

// 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类?


案例3:

// 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

结果:按预期正常工作。


案例4:

// 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类?


为什么扩展ArithmeticExceptionExtenderClass类没有被触发?但是当我直接使用ArithmeticException时,它会被触发。

虽然您已将自定义异常声明为ArithmeticException的子类,但您无法让a / b抛出自定义异常。 JLS 指定(整数)除以零将抛出ArithmeticException;见JLS 15.17.2第3段。

由于引发的异常是ArithmeticException,因此无法将其作为自定义异常捕获。

try {
c = a / b;      
} catch (ExtenderClass ex) {
...
}

将捕获ExtenderClassExtenderClass和子类.ArithmeticException不是ExtenderClass的子类,所以上面不会抓住它。


您创建ExtenderClass的原因是...

我想修改ArithmeticException输出消息。

您最好编写一些特殊情况的代码,以便在打印时用不同的消息代替"/零"消息。

或。。。。

try {
c = a / b;      
} catch (ArithmeticException ex) {
thrown new ExtenderClass("Division by zero is cool!, ex);
}

创建ArithmeticException的子类不会导致在将int除以 0 时引发该子类的实例。

int除以 0 将始终抛出基类ArithmeticException

只有在代码中显式抛出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);
}

查看您的案例:

1)您按预期引起并抓住了ArithmeticExceptionExtenderClass未使用。

2)抛出一个ArithmeticException,并且没有被您的代码捕获,因为ExtenderClassArithmeticException更具体

3)您按预期引起并抓住了ArithmeticException。注意:执行不会达到显式抛出ArithmeticException的程度。

4)你用行c = a / b引起ArithmeticException,它没有被你的代码捕获,因为ExtenderClassArithmeticException更具体。执行未达到显式抛出ExtenderClass的点。

很好的观察。

请找到我的解释:

注意:

  • 根据您的代码片段ArithmeticException超类ExtenderClass子类

  • 在 Java 中catch仅当块中定义的异常与块try中抛出的异常相同或比try块块中引发的异常相同时,才会执行该块。


解释:

  • 案例 1
    在这里,您抛出ArithmeticException并被同一类捕获它,因此 catch 块正在按预期执行。

  • 案例 2
    在这里,您正在向第 9 行扔ArithmeticExceptionc = a / b;并试图通过其子类来捕获这是不可能的。
    因此,异常未在 catch 块中处理。 您应该通过相同或更广泛的异常(超级类)捕获。

  • 案例 3
    这种情况与情况 2 类似,只是您被相同的异常(算术异常)捕获并抛出ArithmeticException2 次

    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);
    }
    

    在这里,您正在尝试通过子类(ExtenderClass) 捕获,这是不可能的。 所以catch块不会处理异常。

相关内容

  • 没有找到相关文章

最新更新