2016-07-10 11 views
0

Ich habe eine einfache Anwendung, die es Benutzern ermöglicht, einen Divisor, einen Divident einzugeben und dann den Quotienten zu berechnen. Ich benutze Vaadin als Rahmen, aber ich denke nicht, dass das zählt. Also habe ich über die Ausnahmen nachgedacht, die auftreten können und das sind diejenigen, die ich identifiziert habe: -Division von 0: ArithmeticException; -Benutzer eine Zeichenfolge statt einer Zahl eingeben: InputMismatchException Hier ist die Klasse, die die Form und befasst sich mit den Ausnahmen erstellt:NumberFormatException: wie man damit umgeht

package my.vaadin.project.exceptionTest; 


import java.awt.Component; 
import java.util.InputMismatchException; 

import com.vaadin.server.Page; 
import com.vaadin.shared.Position; 
import com.vaadin.ui.Button; 
import com.vaadin.ui.Button.ClickEvent; 
import com.vaadin.ui.CustomComponent; 
import com.vaadin.ui.Notification; 
import com.vaadin.ui.TextField; 
import com.vaadin.ui.VerticalLayout; 
import com.vaadin.event.Action; 

public class Calculation extends CustomComponent{ 
    final VerticalLayout vl = new VerticalLayout(); 
    final TextField dividend = new TextField(); 
    final TextField divisor = new TextField(); 

    final TextField result = new TextField(); 
    final Button resetButton = new Button("Reset"); 
    private int divisionResult = 0; 
    Button button = new Button("Click Me"); 

    public Calculation(){ 
     dividend.setCaption("Enter the dividend:"); 
     divisor.setCaption("Enter the divisor:"); 

     result.setCaption("Result"); 
     result.setReadOnly(true); 
     button.addClickListener(new Button.ClickListener(){ 
      @Override 
      public void buttonClick(ClickEvent event) { 
       System.out.println("this is a test"); 
       validateInputs(); 
      }    
     }); 
     resetButton.addClickListener(new Button.ClickListener(){    
      @Override 
      public void buttonClick(ClickEvent event) { 
       setDividend(""); 
       setDivisor("");    
       setResult(""); 
      } 
     }); 
     vl.setMargin(true); 
     vl.setSpacing(true); 
     vl.addComponents(dividend, divisor, button, result); 

    }//end of constructor 
    public void validateInputs(){ 
     System.out.println("theDivisor is " + getDivisor() + " theDividend " + getDividend()); 
     try{ 
      divisionResult = (Integer.parseInt(getDividend())/Integer.parseInt(getDivisor())); 
     } 
     catch(ArithmeticException arithmeticException){ 
      System.err.println("Zero is an invalid denominator!"); 
      createError("Divisor can't be 0!! Please enter a number > 0!"); 
     } 
     catch(InputMismatchException inputMismatchException){ 
      System.err.println("The dividend or divisor are not a number! Please enter a valid number!"); 
      createError("The dividend or divisor are not a number! Please enter a valid number!"); 
     } 
    }//end of validateInputs 
    public String getDivisor(){  
     return divisor.getValue(); 
    } 
    public String getDividend(){   
     return dividend.getValue(); 
    } 
    public void setDivisor(String newDivisor){ 
     divisor.setValue(newDivisor); 
    } 
    public void setDividend(String newDividend){ 
     dividend.setValue(newDividend); 
    } 
    public void setResult(String newResult){ 
     result.setValue(newResult); 
    } 
    public void createError(String errorString){ 
     String error = errorString; 
     Notification notif = new Notification(
       error, 
       Notification.TYPE_ERROR_MESSAGE 
      ); 
      notif.setDelayMsec(20000); 
      notif.show(Page.getCurrent()); 
    } 
} 

ich den Versuch catch-Anweisung verwenden, wenn ich den Quotienten (aber ich haven‘berechnen (t das Ergebnis noch angezeigt)

Wenn ich 0 in den Divisor tippe, dann bekomme ich, was ich erwarte, eine ArithmeticException geworfen und behandelt wird. Allerdings, wenn ich eine Zeichenfolge in die Felder eingeben würde ich gedacht haben, dass die InputMismatchException kümmern würde, aber in der Tat ist dies die Nachricht, die ich in der Konsole Ich sah die NumberFormatException auf und ich bin mir nicht sicher, ob ich verstehe was zu tun ist und warum das passiert. Wie Sie aus dem Code entnehmen können, parse ich die Zeichenfolge in Ganzzahlen, aber es scheint, dass der Compiler es nicht mag. Muss ich eine catch-Anweisung hinzufügen und mich auch mit der NumberFormatException befassen? Sollte die InputMismatchException nicht ausreichen? Bitte lassen Sie mich wissen, was Sie denken

+1

Unter welchen Umständen 'Integer.parseInt (String)' oder Integer-Division einen 'InputMismatchException' werfen? Das wird nur von 'Scanner', [laut Dokumentation] (https://docs.oracle.com/javase/7/docs/api/java/util/InputMismatchException.html) ausgelöst. –

+0

'NumberFormatException: Für Eingabe-String:" iuy "' schlägt vor, die Eingabedaten, möglicherweise durch ein Eingabe/Textfeld gesammelt, Sie versuchen, in eine Zahl zu konvertieren ist eigentlich keine Zahl, genauer gesagt "iuy". Wenn ich mir Ihren Code anschaue, sehe ich nichts durch die 'InputMismatchException', während' Integer.parseInt' eine 'NumberFormatException' auslöst, wenn sie die Zeichenkette nicht in eine Zahl umwandeln kann, so dass Sie wahrscheinlich das falsche erwarten Ausnahme... – Morfic

+0

Mögliches Duplikat von [Was ist eine NullPointerException und wie kann ich sie beheben?] (Http://StackOverflow.com/questions/39849984/what-is-a-nullpointerexception-and-how-can-i-fix-it) – xenteros

Antwort

1

Wenn Sie bei der Dokumentation von Integer.parseInt aussehen es dies angegeben ist:

Wirft: NumberFormatException - wenn die Zeichenfolge eine parsable ganze Zahl nicht enthalten.

Stattdessen die InputMismatchException Dokumentation dies angeben:

von einem Scanner Geworfen, um anzuzeigen, dass das Token für den erwarteten Typ des Musters nicht abgerufen entspricht, oder dass das Token für die außerhalb des zulässigen Bereichs erwarteter Typ

Daher scheint das Programm sich korrekt zu verhalten und entsprechend den Spezifikationen.

Das bedeutet, dass Sie NumberFormatException statt InputMismatchException fangen sollten.

-2

Es gibt sehr seltene Gelegenheiten, wo Sie RuntimeException s fangen würden. Vor allem in Ihrem Geschäftscode ist es ein schlechtes Muster.

Stellen Sie sicher, dass Sie Ihre Eingabewerte vor validieren, die Sie verarbeiten. Sie wissen, dass der Divisor nicht null sein darf. In Ihrem Beispiel sollten Sie die Eingabe von Null für den Divisor in Ihrer GUI zurückweisen, egal, was sie ist (HTML-Eingabeformular, Swing TextField usw.).

Spätestens Ihre Setzer setDivisor() MUSS keine 0 akzeptieren und sich eine Ausnahme, z. eine IllegalArgumentException.

Darüber hinaus sollten Sie die Anliegen Ihres Codes trennen. Mischen Sie die Berechnung von Zahlen nicht mit Ihrer GUI. Die Berechnung sollte in einer anderen Klasse stattfinden, die nichts über Ihre GUI weiß.

PS/EDIT: Der Versuch, zu erklären, warum RuntimeException s Fang ist keine gute Idee:

von Oracle Docs Genommen: http://docs.oracle.com/javase/tutorial/essential/exceptions/catchOrDeclare.html

Die dritte Art von Ausnahme ist die Laufzeitausnahme. Dies sind Ausnahmebedingungen, die für die Anwendung intern sind und die die Anwendung normalerweise nicht antizipieren oder wiederherstellen kann. Diese in der Regel zeigen Programmierfehler ....

In Ihrem Fall kann die Anwendung antizipiert und aus der Tatsache, erholen, dass der Benutzer einen ungültigen Teiler eingegeben. Und noch mehr sollten Sie Ihr Bestes geben, um zu vermeiden, dass der Benutzer ungültige Daten eingibt.

Darüber hinaus einige andere Fragen zu SO, wo die Leute übereinstimmen, dass das Abfangen von RuntimeExceptions ein code smell sind.

Ja, jede RuntimeException zu fangen ist fast immer ein Code-Geruch. Das C2-Wiki scheint zuzustimmen. Is Catching a Null Pointer Exception a Code Smell?

Ein anderes von einer offiziellen Quelle

Ungeprüfter Ausnahmen: Runtime erstreckt sich auch von Exception. Alle Ausnahmen, die von RuntimeException erben, erhalten jedoch die Sonderbehandlung . Es ist nicht erforderlich, dass der Clientcode mit ihnen verarbeitet, und daher werden sie als ungeprüfte Ausnahmen bezeichnet. http://www.onjava.com/pub/a/onjava/2003/11/19/exceptions.html?page=1

Es geht weiter und weiter ...

Ebenso Programme müssen nicht fangen Runtime, Exception oder Throwable. Wenige, wenn überhaupt, Methoden sind in der Lage, alle möglichen Laufzeitausnahmen zu behandeln. https://www.securecoding.cert.org/confluence/display/java/ERR08-J.+Do+not+catch+NullPointerException+or+any+of+its+ancestors

+0

Warum? Die Ausnahme sagt Ihnen, dass sie ungültig ist und "parseInt()" muss dies bereits überprüfen. Warum den ganzen Code wiederholen? – EJP

+0

Siehe die Links zu verschiedenen Websites, die meinen Vorschlag unterstützen. Wenn Sie möchten, können wir dieses Problem über diesen Thread hinaus detaillierter diskutieren. Ich wäre noch glücklicher, wenn Sie die -1-Stimme zurückziehen würden, wenn Sie nicht Ihre Theorie richtig beweisen. – Matt

+0

danke Jungs, ich werde meinen Code aktualisieren und dann die richtigen Ausnahmen verwenden – antobbo

0

Inkompatibilität Ausgabe

Ich habe das gleiche Problem auf Android Studio 0.8.7. Aber es funktioniert gut mit Android Studio 2.1. Ich denke, es sollte behoben werden, indem Android Studio und Gradle Plugin auf die neueste Version aktualisiert werden.

Glück

Verwandte Themen