Throw in Lambda bzw. innere Klasse

08/05/2017 14:20 MIZAN#1
Hallo,

ich sitze gerade an einer Aufgabe, wo bei einem Fehlschlag beim konvertieren des Inhalts der Textfelder in int-Werte, die Temperatur Exception geworfen werden soll.
Meine Idee war, dass ich die NumberFormatException auffange und im catch-Block die TemperaturException werfe.
Leider tritt dabei der Fehler auf:
"unreported exception TemperaturException; must be caught or declared to be thrown".
Als Vorschlag gab er mir, dass ich es in einen try-catch Block schreibe (siehe unten). Das sieht mir aber nicht ganz sauber aus. Gibt es eine bessere Lösung?


Zudem soll der Inhalt der Exception widergeben, in welchem Textfeld der Fehler liegt. Deswegen dachte ich, mache ich zwei try-catch Blöcke.

Code:
but.setOnAction(e->{
            try {
            int fahrenheit = Integer.parseInt(fah.getText());
        } catch(NumberFormatException en ) { 
            try {
            throw new TemperaturException("Bitte nur eine Zahl in Fahrenheit eingeben.");
                } catch (TemperaturException ex) {
                    ex.printStackTrace();
                }
        }
        
        try {
            int celsius = Integer.parseInt(cel.getText());
        } catch(NumberFormatException ef ) { 
                try {
                    throw new TemperaturException("Bitte nur eine Zahl unter Celsius ausgeben.");
                } catch (TemperaturException ex) {
                    ex.printStackTrace();
                }
        }
        });
08/05/2017 14:49 Menan#2
@[Only registered and activated users can see links. Click Here To Register...]

Deine TemperatrException ist ja eine "custom" Exception.

Eventuell zeigst du noch deine Implementierung der Exception. Ich denke nämlich, dass du sie als normale Exception deklariert hast, welche deklariert (method throws TemperaturException) und/oder abgefangen werden muss.

Eine einfache Abhilfe wäre es, die Exception als RuntimeException zu deklarieren, dann fliegt sie einfach und der Stacktrace wird ausgegeben.
08/05/2017 15:09 MIZAN#3
Quote:
Originally Posted by Menan View Post
@[Only registered and activated users can see links. Click Here To Register...]
Ich denke nämlich, dass du sie als normale Exception deklariert hast, welche deklariert (method throws TemperaturException) und/oder abgefangen werden muss.
Ist damit gemeint, dass hinter die Methode "throws TemperaturException" stehen muss?
Das hatte ich ja gemacht.
Ich zeig mal den ganzen Code.
Code:
public class CelsiusFahrenheit extends Application{

    [MENTION=295804]Override[/MENTION]
    public void start(Stage ps) throws TemperaturException {
        BorderPane bp = new BorderPane();
        TextField cel = new TextField();
        TextField fah = new TextField();
        Button but = new Button("OK");
        VBox vb = new VBox();
        vb.getChildren().addAll(cel,fah,but);
        
        but.setOnAction(e->{
            try {
            int fahrenheit = Integer.parseInt(fah.getText());
        } catch(NumberFormatException en ) { 
            throw new TemperaturException("Bitte nur eine Zahl in Fahrenheit eingeben.");
        }
        
        try {
            int celsius = Integer.parseInt(cel.getText());
        } catch(NumberFormatException ef ) { 
                try {
                    throw new TemperaturException("Bitte nur eine Zahl unter Celsius ausgeben.");
                } catch (TemperaturException ex) {
                    ex.printStackTrace();
                }

        }
        });
        
        bp.setCenter(vb);
        Scene scene = new Scene(bp);
        ps.setScene(scene);
        ps.show();
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

So habe ich die custom Exception geschrieben.

Code:
public class TemperaturException extends Exception{
    
    public TemperaturException() {
        super();
    }
    
    public TemperaturException(String t) {
        super(t);
    }
}
Wenn ich die Exception als RuntimeException deklariere, klappt es.
Danke.

Ich habe aber noch nicht ganz verstanden, wieso es vorher bei mir nicht geklappt hat.
08/05/2017 15:22 Menan#4
Ja, wenn du eine normale Exception deklarierst, dann muss die Exception entweder in der Methode abgefangen werden oder angegeben werden, dass diese Methode eine Exception werfen kann, dies wäre genau das "throws TemperaturException".
Allerdings muss diese Exception dann von der Methode, die diese Methode aufruft behandelt werden.

Eine RuntimeException kann zur Laufzeit auftreten (wie der Name schon sagt). Diese muss nicht, aber kann behandelt werden.

Eventuell solltest du dich nochmal mit dem Unterschied zwischen Exception und RuntimeException befassen :)

In deinem Fall sollte diese Exception eigentlich keine RuntimeException sein, da du ja ein Programm schreibst und diese Exception auf eine Fehlerhafte Eingabe hinweist. Also würdest du normalerweise diese Exception auffangen (catch) und z.B. eine Fehlermeldung ausgeben.
Wenn du nun allerdings wirklich nur den StackTrace möchtest, kannst du sie erstmal einfach als RuntimeException deklarieren und sparst dir nen bisschen Code.
@[Only registered and activated users can see links. Click Here To Register...]
08/06/2017 17:00 MIZAN#5
Mir ist noch aufgefallen, dass mein erster Lösungsansatz (der im ersten Post) ausserhalb des Lambas funktioniert. Wieso funktioniert es nicht innerhalb?