#java #exception #runtimeexception
#java #исключение #исключение runtimeexception
Вопрос:
У меня есть простая программа с выбрасыванием исключений, и я понимаю, что получаю результат, но не исключение, которое я получаю. Вот код:
//Q1.java
import java.io.*;
import java.util.*;
public class Q1{
public static void main(String args[]){
Q1 q1=new Q1();
Q2 q2=new Q2();
try{
System.out.println(q2.method(q1));
System.out.println(q2.method(q2));
}catch(QE1 e){
System.out.println("exception 1");
}finally{
System.out.println("finally");
}
}
Object method(Q1 q) throws QE1{
if(q instanceof Q1){
System.out.println("method");
}
else {
throw new QE2();
}
return 1;
}
}
class Q2 extends Q1{
Object method(Q1 q) throws QE1{
if(errorCheck()amp;amp; q instanceof Q2){
throw new QE2("error 2");
}else if(q instanceof Q2){
throw new QE1();
}else{
return new String("abc");
}
}
boolean errorCheck(){
return true;
}
}
class QE1 extends Throwable{
public QE1(){
System.out.println("qe1 - 1");
}
public QE1(String s){
super(s);
System.out.println("qe1 - 2");
}
}
class QE2 extends RuntimeException {
public QE2(){
System.out.println("qe2 - 1");
}
public QE2(String s){
this();
System.out.println("qe2 - 2");
}
}
Вывод:
abc
qe2 - 1
qe2 - 2
finally
QE2
at Q2.method(Q1.java:33)
at Q1.main(Q1.java:10)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
а затем программа прерывается, но я не уверен, почему.
Проблемная строка — это строка в конструкторе QE2.
Я как бы предполагаю, что, поскольку QE2 является подклассом RuntimeException, и по этой причине вызывается конструктор RuntimeException, поэтому программа прерывается.
Это так или что-то еще?
Комментарии:
1. Что вы имеете в виду под «перерывами». Пожалуйста, добавьте трассировку стека, которую вы получаете! Видите ли, этот код, вероятно, специально написан так, чтобы его было трудно читать. Вы действительно думаете, что это хороший вклад для других людей? Нам в 10 раз сложнее помочь вам; просто из-за этого чрезмерно сложного кода.
2. получаете ли вы трассировку стека в командной строке? если это так, пожалуйста, покажите.
3. Также может быть полезно дать вашим именам классов и методов что-то значимое. Вызов его «Q1» и «Q2» и «метод» очень быстро приведет вас в замешательство. Вы можете делать то, что хотите, но это плохая практика, imo.
4. Успокойтесь все. Обычно я не пишу такой код, запутанный и неинформативный. Я готовлюсь к экзамену, и это должно сбивать с толку. Кроме того, я добавил трассировку стека.
5. @misty Я дал вам ответ ниже. Насколько я могу судить, в вашем коде не происходит ничего неожиданного.
Ответ №1:
В выводе / поведении вашего кода нет ничего неожиданного.
public static void main(String args[]) {
Q1 q1 = new Q1();
Q2 q2 = new Q2();
try {
// this prints "abc" and no exception is thrown
System.out.println(q2.method(q1));
// this throws a new QE2(), which prints
// this prints "qe2 - 1" followed by "qe2 - 2"
System.out.println(q2.method(q2));
} catch(QE1 e) {
System.out.println("exception 1");
} finally {
// your code ends up here, which prints "finally"
System.out.println("finally");
}
}
Вы создаете исключение типа QE2
в try
блоке вашего main
метода. Однако на самом деле вы никогда не перехватываете исключения такого типа, поскольку вы только перехватываете QE1
. В результате вы попадаете в finally
блок, который печатает "finally"
.
Если вы хотите перехватить все исключения, то вы можете использовать catch (Exception e)
прямо перед finally
блоком.
Комментарии:
1. Я понимаю, какая программа печатает. Но почему я получаю исключение?
2. Вы создаете исключение типа
QE2
, но не перехватываете его. Как вы думаете, что означает выбрасывание исключения?3. Да, я это знаю. Большое вам спасибо! Одна вещь, которая остается запутанной, заключается в следующем: не следует ли перехватывать блок с
QE1
перехватом всех исключений, поскольку он является подклассом Throwable ?4. @misty
QE1
является подклассомThrowable
, но не подклассомException
, поэтому именно поэтомуQE2
не перехватывается.5. Это сбивает меня с толку, потому что, если бы это было
catch(Throwable e)
,QE2
было бы поймано…