Java - Почему подкласс класса ArithmeticException не вызывается? - PullRequest
0 голосов
/ 31 декабря 2018

Я хочу изменить выводимое сообщение 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 ]

0 голосов
/ 31 декабря 2018

Приятное наблюдение.

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

ПРИМЕЧАНИЕ:

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

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


ОБЪЯСНЕНИЯ:

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

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

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

0 голосов
/ 31 декабря 2018

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

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);
}
0 голосов
/ 31 декабря 2018

Хотя вы объявили пользовательское исключение в качестве подкласса 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);
}
0 голосов
/ 31 декабря 2018

Создание подкласса ArithmeticException не приводит к выбросу экземпляра этого подкласса при делении int на 0.

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

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

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

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

0 голосов
/ 31 декабря 2018

Рассмотрение ваших дел:

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

2) ArithmeticException выбрасывается и не перехватывается вашим кодом, так как ExtenderClass является более конкретным , чем ArithmeticException.

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

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

...