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
на линии № 9c = 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
Блок не будет обрабатывать исключение.