2016-10-17 2 views
0

J'ai un programme simple avec des exceptions de lancement, et je comprends la sortie que je reçois, mais pas l'exception que je reçois. Voici le code:Le programme Java simple se brise en lançant l'exception

//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"); 
    } 

} 

sortie est:

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) 

puis pauses programme, mais je ne sais pas pourquoi.
La ligne problématique est celle du constructeur de QE2.
Je suppose que, parce que QE2 est sous-classe de RuntimeException et pour cette raison, le constructeur de RuntimeException est appelé, donc le programme se brise.
Est-ce le cas ou autre chose?

+0

Que voulez-vous dire par "pauses". S'il vous plaît ajouter la trace de la pile que vous obtenez! Vous voyez, ce code est probablement écrit exprès pour être difficile à lire. Pensez-vous vraiment que c'est une bonne entrée pour les autres? Vous rendez 10 fois plus difficile pour nous de vous aider; juste à cause de ce code trop compliqué là-bas. – GhostCat

+0

obtenez-vous un stacktrace à la ligne de commande? Si oui, s'il vous plaît montrer. –

+1

Il pourrait également être utile de donner un sens à vos noms de classe et de méthode. L'appeler "Q1" et "Q2" et "méthode" vous rendra confus très rapidement. Vous pouvez faire ce que vous voulez mais c'est une mauvaise pratique. – Matt1776

Répondre

1

La sortie/le comportement de votre code n'a rien d'inattendu.

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"); 
    } 
} 

Vous jetez une exception de type QE2 dans le bloc try de votre méthode main. Cependant, vous n'attrapez jamais ce type d'exception, car vous ne saisissez que QE1. Par conséquent, vous vous retrouvez dans le bloc finally, qui imprime "finally". Si vous souhaitez capturer toutes les exceptions, vous pouvez utiliser catch (Exception e) juste avant le bloc finally.

+0

Je comprends quel programme imprime. Mais pourquoi ai-je une exception? – misty

+0

Vous tombez _throw_ une exception de type 'QE2', mais vous ne l'attrapez pas. Que pensez-vous de lancer une exception? –

+0

Oui, je le sais. Merci beaucoup! Une chose qui prête à confusion est la suivante: ne devrait pas attraper le bloc avec les exceptions catch * all * de 'QE1', puisqu'il s'agit d'une sous-classe de Throwable? – misty