2016-10-17 5 views
0

У меня есть простая программа с исключениями для исключения, и я понимаю вывод, который я получаю, но не исключение, которое я получаю. Вот код:Простая программа Java разрывается при бросании исключения

//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()&& 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, поэтому программа прерывается.
В этом случае или что-то еще?

+0

Что вы имеете в виду с «перерывами». Пожалуйста, добавьте трассировку стека, которую вы получите! Вы видите, этот код **, возможно, специально написанный, который трудно читать. Вы действительно думаете, что это хороший вклад для других людей? Вы делаете это в 10 раз сложнее для нас, чтобы помочь вам; просто из-за этого сложного кода. – GhostCat

+0

Вы получаете стек в командной строке? если так пожалуйста показывать. –

+1

Также может быть полезно дать вашему классу и методу имена что-то значимое. Вызов «Q1» и «Q2» и «метод» заставит вас смутить очень быстро. Вы можете делать то, что хотите, но это плохая практика imo. – Matt1776

ответ

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.

+0

Я понимаю, какая программа печатает. Но почему я получаю исключение? – misty

+0

Вы _throw_ исключение типа 'QE2', но вы его не поймаете. Что, по-вашему, бросает исключение? –

+0

Да, я понимаю. Большое спасибо! Одна вещь, остающаяся запутанной, заключается в следующем: не следует ловить блок с помощью 'QE1' catch * all * exceptions, так как это подкласс Throwable? – misty