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 учебный класс?


Почему ExtenderClass класс, который расширяет ArithmeticException не уволен? Но когда я использую ArithmeticException непосредственно, это уволено.

5 ответов

Решение

Хотя вы объявили пользовательское исключение в качестве подкласса ArithmeticException, нет способа, которым вы можете получить a / b бросить ваше пользовательское исключение. JLS указывает, что (целое) деление на ноль будет выбрасывать ArithmeticException; см. JLS 15.17.2 пункт 3.

Поскольку выбрасываемое исключение ArithmeticExceptionвы не сможете отловить его как свое собственное исключение.

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

будет ловить ExtenderClass и подклассы ExtenderClass, ArithmeticException не подкласс ExtenderClassтак что вышеизложенное не уловит.


Ваша причина для создания ExtenderClass является...

Я хочу изменить ArithmeticException выходное сообщение.

Было бы лучше написать какой-нибудь специальный код для замены другого сообщения на "/ ноль" при его распечатке.

Или же....

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

Как объяснено в комментариях:

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 не вызывает выброс экземпляра этого подкласса при разделении int на 0

Разделение int на 0 всегда будет бросать базу ArithmeticException учебный класс.

Ваш ExtenderClass будет выброшено, только если вы явно в своем коде:

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

В единственном случае вы явно бросаете ExtenderClass (случай 4), этот оператор throw никогда не достигается, так как предыдущий оператор вызывает ArithmeticException быть брошенным.

Рассматривая ваши дела:

1) Вы вызываете и ловите ArithmeticException как и ожидалось. ExtenderClass не используется.

2) Ан ArithmeticException брошен и не пойман вашим кодом как ExtenderClass более конкретно, чем ArithmeticException,

3) Вы вызываете и ловите ArithmeticException как и ожидалось. Примечание: выполнение не достигает точки, в которой вы явно бросаете ArithmeticException,

4) Вы вызываете ArithmeticException с линией c = a / b и он не улавливается вашим кодом как ExtenderClass более конкретно, чем ArithmeticException, Выполнение не достигает точки, где вы явно бросаете ExtenderClass,

Хорошее наблюдение.

Пожалуйста, найдите мои объяснения:

НОТА:

  • Согласно фрагменту кода ArithmeticException это суперкласс и ExtenderClass это подкласс

  • На яве catch блок будет выполняться, только если определенное внутри него исключение совпадает с исключением, выданным в try блок или шире чем try блок.


ПОЯСНЕНИЯ:

  • Случай 1
    Здесь вы бросаете ArithmeticException и перехватывает его одним и тем же классом, поэтому блок catch выполняется, как и ожидалось.

  • Дело 2
    Здесь вы бросаете ArithmeticException на линии № 9 c = a / b; и пытается поймать его подклассом, что невозможно.
    Таким образом, исключение не было обработано в блоке catch. Вы должны поймать с тем же или более широким исключением (супер класс).

  • Дело 3
    Этот случай аналогичен случаю 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 поэтому будет выдано только 1-е исключение, и управление никогда не перейдет в секунду, как показано в приведенном ниже коде.

    try{
        c = a / b;
        throw new ExtenderClass();
    }catch(ExtenderClass e){
        System.out.println("I caught: " + e);
    }
    

    Здесь вы пытаетесь поймать по подклассу (ExtenderClass) что не возможно. так catch Блок не будет обрабатывать исключение.

Другие вопросы по тегам