Ausnahmebehandlung

popa1980

Mitglied
Hi, ich habe hier eine Aufgabe die mir bei zwei gleichen Anweisungszweigen unterschiedlich reagiert!
und zwar soll das Program eine NullPointerException auslösen wenn "Abbrechen" gedrückt wird.
Eingelesen wird einmal ein int-Wert und einmal ein double-Wert.
Soweit so gut, wenn ich den Code laufen lasse, funktioniert das Abbrechen im ersten Dialog nicht richtig,
da anstelle der NullPointerException eine NumberFormatException ausgelöst wird. Im zweiten Dialog (für den double-Wert) hingegen geht das problemlos!

Hier der Code für die klasse:
Java:
/************************************************** *********************************
* Eine Klasse für Eingaben über einen grafischen Dialog
* ************************************************** *******************************
* Das Einlesen erfolgt über eine überladene statische Funktion einlesen()
* Die Klassenvariable abgebrochen speichert, ob die Eingabe über die
* Schaltfläche Abbrechen abgebrochen wurde
* ************************************************** *******************************
* Beschreibung der Methode einlesen()
* 
* Die Methode liest über die Methode lesen() einen Wert ein und versucht,
* diesen Wert in den passenden Typ umzuwandeln. Die Eingabe wird so lange
* wiederholt, bis ein gültiger Typ eingegeben wurde bzw. auf die Schaltfläche
* Abbrechen geklickt wurde.
* 
* Parameter:	wert für den Typ, der verarbeitet werden soll
* Rückgabe:	Der Wert der umgewandelt wurde
* Der Typ hängt vom übergebenen Parameter ab.
* 
* Die Methode ist drei mal vorhanden (für int, float und double)
* 
* ************************************************** *******************************
* Beschreibung der Methode lesen()
*
* Die Methode wird zum Einlesen der Werte über den Dialog benutzt.
* 
* Parameter:	text als Zeichenkette für die Ausgabe im Dialog
* Rückgabe:	Der eingelesene Wert als Zeichenkette
* ************************************************** *******************************
* 
*	*/

//Die Klasse befindet sich im Package eindialog
package eindialogV2;

//Für den Eingabedialog
import javax.swing.JOptionPane;


public class EingabeDialogV2 {

//Die Klassenvariable abgebrochen
public static boolean abgebrochen;


//Die Hilfsmethode zum einlesen der Daten über den Dialog
//Beschreibung siehe oben!
private static String lesen(String text) throws NullPointerException {

String eingabeTemp;

eingabeTemp = JOptionPane.showInputDialog("Bitte geben Sie einen " + text + " Wert ein:");
return (eingabeTemp);
}



//Die Überladene Methode einlesen() für den Typ int
//Beschreibung siehe oben
public static int einlesen(int wert){

int wertTemp = 0;
boolean gelungen = false;
String eingabeTemp;

abgebrochen = false;

while (gelungen == false) {
//Die Eingabe lesen
eingabeTemp = lesen("int");

//Wenn nicht auf Abbrechen geklickt wurde,
//wird versucht die Eingabe in den Typ int
//umzuwandeln
try {
wertTemp = Integer.parseInt(eingabeTemp);
gelungen = true;
}	
catch (NullPointerException e) {
gelungen = true;
abgebrochen = true;
System.out.println("Ausnahme NullPointerException1");
}
catch (NumberFormatException e) {
//Ausgabe über Grafischen Dialog
JOptionPane.showMessageDialog(null, "Ihre Eingabe war nicht gültig. Bitte wiederholen...");
}
}

//Den Wert zurückliefern
//Wenn die Eingabe abgebrochen wurde, wird 0 geliefert
return wertTemp;
}

//Die überladene Methode einlesen() für den Typ double
//Beschreibung siehe oben bzw. bei der Methode für den int Typ
public static double einlesen(double wert) {
double wertTemp = 0;
boolean gelungen = false;
String eingabeTemp;

abgebrochen = false;

while (gelungen == false) {
eingabeTemp = lesen("double");
try {
wertTemp = Double.parseDouble(eingabeTemp);
gelungen = true;
}
catch (NullPointerException e) {
gelungen = true;
abgebrochen = true;
System.out.println("Ausnahme NullPointerException2");
}	
catch (NumberFormatException e) {
//Eine Ausgabe über einen grafischen Dialog
JOptionPane.showMessageDialog(null, "Ihre Eingabe war ungültig. Bitte wiederholen...");
}
}

return wertTemp;
}

//Die überladene Methode einlesen() für den Typ float
//Beschreibung siehe oben bzw. bei der Methode für den int Typ
public static float einlesen(float wert) {
float wertTemp = 0F;
boolean gelungen = false;
String eingabeTemp;
while (gelungen == false) {
eingabeTemp = lesen("double");
try {
wertTemp = Float.parseFloat(eingabeTemp);
gelungen = true;
}
catch (NullPointerException e) {
gelungen = true;
abgebrochen = true;
System.out.println("Ausnahme NullPointerException3");
}
catch (NumberFormatException e) {
//Eine Ausgabe über einen grafischen Dialog
JOptionPane.showMessageDialog(null, "Ihre Eingabe war ungültig. Bitte wiederholen...");
}	
}
return wertTemp;
}
}

Und hier noch die Klasse mit der Main-Methode:


Java:
import eindialogV2.EingabeDialogV2;

/*################################################# ##############
* Ein Test der Klasse EingabeDialog
* Die Klasse wird über einen Verweis
* eingebunden
################################################## #############*/

public class EingabeDialogTest {

public static void main(String[] args) {
int intWert = 0;
double doubleWert = 0;

//Der Aufruf der Methode einlesen() mit einem int- Typen
intWert = EingabeDialogV2.einlesen(intWert);
if (EingabeDialogV2.abgebrochen == true)
System.out.println("Sie haben die Eingabe abgebrochen");
else
System.out.println("Sie haben " + intWert + " eingegeben.");

//Und nun der Test mit double- Typen
doubleWert = EingabeDialogV2.einlesen(doubleWert);
if (EingabeDialogV2.abgebrochen == true)
System.out.println("Sie haben die Eingabe abgebrochen");
else
System.out.println("Sie haben " + doubleWert + " eingegeben.");

}

}

Was habe ich übersehen? ich habs jetzt schon zig mal durch den debugger laufen lassen und ich find es nicht...!

Danke im voraus!
 

AquaBall

Top Contributor
Ein paar Tips:
1) Versuchs mit Formatierung, dann findest du dich zurecht.
2) solche Kommentare sind überflüssig
Code:
public static boolean	abgebrochen;	//Die Klassenvariable abgebrochen
3) bei float fehlt
Code:
abgebrochen = false;
4) text == String, ich würde die Variable so benennen wie sie verwendet wird: zB
Code:
varTyp
4) zur Frage: Du fängst die NPE gar nicht ab! Das
Code:
lesen
gehört ins
Code:
try
5) Aber das Ganze sollte doch eleganter mit generics zu lösen sein, statt CodeDup
6) Warum willst du diese Konstruktion überhaupt, statt simpler TypumWandlung?

Java:
package eindialogV2;

import javax.swing.JOptionPane; //Für den Eingabedialog

public class EingabeDialogV2 {
	public static boolean	abgebrochen;

	/** Die Hilfsmethode zum Einlesen der Daten über den Dialog  (Beschreibung siehe oben!)
	 * @param varTyp Typ des einzulesenden Wertes
	 * @return
	 * @throws NullPointerException
	 */
	private static String lesen(String varTyp) throws NullPointerException {
		String eingabeTemp;
		eingabeTemp = JOptionPane.showInputDialog("Bitte geben Sie einen " + varTyp + " Wert ein:");
		return (eingabeTemp);
	}

	/** Die Überladene Methode einlesen() für den Typ int (Beschreibung siehe oben)
	 * @param wert
	 * @return Wenn die Eingabe abgebrochen wurde, wird 0 geliefert
	 */
	public static int einlesen(int wert) {
		int wertTemp = 0;
		boolean gelungen = false;
		String eingabeTemp;

		abgebrochen = false;

		while (gelungen == false) {
			try {
				eingabeTemp = lesen("int");
				//Wenn nicht auf Abbrechen geklickt wurde,
				//wird versucht die Eingabe in den Typ int umzuwandeln
				wertTemp = Integer.parseInt(eingabeTemp);
				gelungen = true;
			} catch (NullPointerException e) {
				gelungen = true;
				abgebrochen = true;
				System.out.println("Ausnahme NullPointerException1");
			} catch (NumberFormatException e) {
				//Ausgabe über Grafischen Dialog
				JOptionPane.showMessageDialog(null, "Ihre Eingabe war nicht gültig. Bitte wiederholen...");
			}
		}

		return wertTemp;  
	}

	//Die überladene Methode einlesen() für den Typ double
	//Beschreibung siehe oben bzw. bei der Methode für den int Typ
	public static double einlesen(double wert) {
		double wertTemp = 0;
		boolean gelungen = false;
		String eingabeTemp;

		abgebrochen = false;

		while (gelungen == false) {
			try {
				eingabeTemp = lesen("double");
				wertTemp = Double.parseDouble(eingabeTemp);
				gelungen = true;
			} catch (NullPointerException e) {
				gelungen = true;
				abgebrochen = true;
				System.out.println("Ausnahme NullPointerException2");
			} catch (NumberFormatException e) {
				//Eine Ausgabe über einen grafischen Dialog
				JOptionPane.showMessageDialog(null, "Ihre Eingabe war ungültig. Bitte wiederholen...");
			}
		}

		return wertTemp;
	}

	//Die überladene Methode einlesen() für den Typ float
	//Beschreibung siehe oben bzw. bei der Methode für den int Typ
	public static float einlesen(float wert) {
		float wertTemp = 0F;
		boolean gelungen = false;
		String eingabeTemp;

		abgebrochen = false;

		while (gelungen == false) {
			try {
				eingabeTemp = lesen("double");
				wertTemp = Float.parseFloat(eingabeTemp);
				gelungen = true;
			} catch (NullPointerException e) {
				gelungen = true;
				abgebrochen = true;
				System.out.println("Ausnahme NullPointerException3");
			} catch (NumberFormatException e) {
				//Eine Ausgabe über einen grafischen Dialog
				JOptionPane.showMessageDialog(null, "Ihre Eingabe war ungültig. Bitte wiederholen...");
			}
		}
		return wertTemp;
	}
}
 
S

SlaterB

Gast
der Unterschied ist, dass Double.parseDouble() und Integer.parseInt() unterschiedlich auf null reagieren,
unschön, aber darauf solltest du dich eh nicht verlassen, besonders nicht wenn du extra Einlesen-Methoden schreibst,

du kannst doch mit if auf null vergleichen und dann reagieren, extra dafür einen try/catch-Block zu schreiben ist unschön,
auch wenn der freilich trotzdem bleiben muss für sonstige Fehler, also catch(NumberFormatException)

catch (NullPointerException) ist höchst fraglich, für eigene Parameter quasi immer falsch,

noch schlimmer ist ja nur noch 'throws NullPointerException' an der lesen-Methode,
dort wird diese Exception nicht extra geworfen,
ist auch sonst nicht häufiger als gewöhnlich zu erwarten, gar praktisch auszuschließen beim aktuellen Code,
und für solche Exceptions muss man gar kein throws ranschreiben,falls nicht für Dokumentation/ als Hinweis
 

popa1980

Mitglied
Ich hatte vergessen zu schreiben das ich noch kein Programierer bin sondern erst werde...!:oops:
Habt daher bitte Nachsicht mit evetuellen Anfängerfehlern! ;)

Ich verwende Win7 64bit / Eclipse

Ein paar Tips:
1) Versuchs mit Formatierung, dann findest du dich zurecht.
2) solche Kommentare sind überflüssig
Code:
public static boolean	abgebrochen;	//Die Klassenvariable abgebrochen
3) bei float fehlt
Code:
abgebrochen = false;
4) text == String, ich würde die Variable so benennen wie sie verwendet wird: zB
Code:
varTyp
4) zur Frage: Du fängst die NPE gar nicht ab! Das
Code:
lesen
gehört ins
Code:
try
5) Aber das Ganze sollte doch eleganter mit generics zu lösen sein, statt CodeDup
6) Warum willst du diese Konstruktion überhaupt, statt simpler TypumWandlung?

zu 1) was genau meinst du mit "Formatierung"? ???:L
zu 2) weiß ich, stand halt so im Buch...
zu 3) hab ich wohl vergessen... hat zwar keine Auswirkungen auf den Ablauf weil es eh nicht aufgerufen wird... sieht aber doof aus und währe natürlich ganz schlecht wenn es ein "richtiges" Prog. werden würde...!
zu 4) (also die 1te 4...) :D siehe "zu 2)"
zu 4.2) wieso funktioniert die allergleiche Konstruktion denn dann bei double? da wird so wie ich das haben will eine NPE ausgelöst!
zu 5) was sind generics??? und CodeDup????
zu 6) Klar könnte man das ganz gut anderst lösen... ich muss halt den Originalcode so umschreiben das es mir eben eine Exception wirft (aber nicht die NumberFormatException....)
 

popa1980

Mitglied
Wo drückst du "Abbrechen"? Wie sieht Eingabe -> Ausgabe jeweils aus?

beim Programmstart erscheint ein Eingabedialog:
(Zeile 13 - 17)
Java:
    private static String lesen(String varTyp) throws NullPointerException {
        String eingabeTemp;
        eingabeTemp = JOptionPane.showInputDialog("Bitte geben Sie einen " + varTyp + " Wert ein:");
        return (eingabeTemp);
    }

wenn man hier auf Abbrechen drückt wird ja der Wert Null zurückgeliefert.
wenn ich das bei der Abfrage für Integer mache, wird eine NumberFormatException ausgelöst,
bei dem Typ Double wird mit der allergleichen Konstruktion, die gewünschte NullPointerException ausgelöst! :bahnhof:
 

popa1980

Mitglied
der Unterschied ist, dass Double.parseDouble() und Integer.parseInt() unterschiedlich auf null reagieren,
unschön, aber darauf solltest du dich eh nicht verlassen, besonders nicht wenn du extra Einlesen-Methoden schreibst,

du kannst doch mit if auf null vergleichen und dann reagieren, extra dafür einen try/catch-Block zu schreiben ist unschön,
auch wenn der freilich trotzdem bleiben muss für sonstige Fehler, also catch(NumberFormatException)

catch (NullPointerException) ist höchst fraglich, für eigene Parameter quasi immer falsch,

noch schlimmer ist ja nur noch 'throws NullPointerException' an der lesen-Methode,
dort wird diese Exception nicht extra geworfen,
ist auch sonst nicht häufiger als gewöhnlich zu erwarten, gar praktisch auszuschließen beim aktuellen Code,
und für solche Exceptions muss man gar kein throws ranschreiben,falls nicht für Dokumentation/ als Hinweis

Die verhalten sich unterschiedlich? ???:L beim vergleich von String zu int/float/double verstehe ich das ja noch aber das Typen für die Verarbeitung von Zahlen auch unterschiedlich reagieren... wie soll man denn da ordentliche Ausnahmebehandlungen programmieren??
Im Original war ein Vergleich mit if auf null, allerdings sollte ich genau das durch eine Ausnahmebehandlung ersetzen :(

Das 'throws NullPointerException' ist wohl noch ein Relikt aus forhergehenden versuchen....:oops: wird entfernt! :)
 
S

SlaterB

Gast
nun, ich sehe keine Lösung, null wird (im einen Fall) zur NumberFormatException genau wie falsche Eingabe,
im catch den Exception-Text anzuschauen wäre irre,
halbwegs noch denkbar erst dort schauen, ob der Parameter null ist, aber das immer noch auch schon vorher passieren

> zu 1) was genau meinst du mit "Formatierung"?

Einrückung, siehe Code von AquaBall, vorne Leerzeichen bzw. Tabs

> zu 5) was sind generics??? und CodeDup????

zu hoch, nicht dran denken, du bleibst bei doppelten Code
 

popa1980

Mitglied
nun, ich sehe keine Lösung, null wird (im einen Fall) zur NumberFormatException genau wie falsche Eingabe,
im catch den Exception-Text anzuschauen wäre irre,
halbwegs noch denkbar erst dort schauen, ob der Parameter null ist, aber das immer noch auch schon vorher passieren

> zu 1) was genau meinst du mit "Formatierung"?

Einrückung, siehe Code von AquaBall, vorne Leerzeichen bzw. Tabs

> zu 5) was sind generics??? und CodeDup????

zu hoch, nicht dran denken, du bleibst bei doppelten Code

sehe ich genauso! ;( Ich hab´s jetzt mal so eingereicht... vielleicht hat ja mein Dozent eine Lösung..!

Das mit dem Einrücken ist wohl passiert weil ich den code vorher schon in einem anderen Forum gepostet hatte und von dort in dieses Forum rauskopiert habe... :oops:
Ich rücke natürlich beim schreiben alles ordentlich ein ;)
Danke für die Mühe! :applaus:
 

Ähnliche Java Themen


Oben