2

我想修改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

结果:按预期工作正常。


案例二:

// 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课程?


为什么ExtenderClass扩展的类ArithmeticException没有被解雇?但是当我ArithmeticException直接使用时,它会被解雇。

4

5 回答 5

2

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

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

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

将捕获ExtenderClass和 的子类ExtenderClassArithmeticException不是子类,所以上面不会捕捉到它。ExtenderClass


你创作的理由ExtenderClass是……

我想修改ArithmeticException输出消息。

您最好编写一些特殊情况代码,以便在打印出来时用不同的消息替换“/ zero”消息。

或者 ....

try {
   c = a / b;      
} catch (ArithmeticException ex) {
   thrown new ExtenderClass("Division by zero is cool!, ex);
}
于 2018-12-31T06:08:48.930 回答
2

创建一个 的子类ArithmeticException不会导致当您将 anint除以 0 时抛出该子类的实例。

除以int0 将始终抛出基ArithmeticException类。

仅当您ExtenderClass在代码中明确抛出时才会抛出:

    try {
        c = a / b;
    } catch(ArithmeticException e) {
        throw new ExtenderClass ();
    }

在您显式抛出的唯一情况ExtenderClass(案例 4)中,永远不会到达该 throw 语句,因为前一个语句会导致ArithmeticException被抛出。

于 2018-12-31T06:09:11.283 回答
2

正如评论中所解释的:

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);
}
于 2018-12-31T06:09:27.530 回答
1

审查您的案例:

ArithmeticException1)您按预期导致并捕获。ExtenderClass未使用。

2) AnArithmeticException被抛出并且不会被您的代码捕获,因为ExtenderClassArithmeticException.

3)你引起并按ArithmeticException预期捕获。注意:执行没有达到你明确抛出ArithmeticException.

4)您导致 an ArithmeticExceptionwith 该行c = a / b并且它没有被您的代码捕获,因为ExtenderClassArithmeticException. 执行没有达到显式抛出ExtenderClass.

于 2018-12-31T06:05:24.500 回答
1

很好的观察。

请找到我的解释:

笔记:

  • 根据您的代码片段ArithmeticExceptionSuperClass并且ExtenderClassSubClass

  • 在 Javacatch块中,只有当其中定义的异常与块中抛出的异常相同try或比try块更广泛时才会执行。


说明:

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

  • 案例 2
    在这里,您在ArithmeticException行投掷。9c = a / b; 并试图通过它的子类来捕捉,这是不可能的。
    所以异常没有在 catch 块中处理。您应该捕获相同或更广泛的异常(超类)。

  • 案例 3
    这个案例类似于案例 2,除了你被相同的异常(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块不会处理异常。

于 2018-12-31T07:26:36.813 回答