Exception handling

tanechka

Bekanntes Mitglied
Hallo,

ich habe ein Programm, in dem eine "unchecked exception " ArrayIndexOutOfBoundsException geworfen wird. Die wird durch den catch-block(RuntimeException) gefangen. Wenn ich einen zusätzlichen catch-block mit NullPointerException aufnehmen, gibt es schon ein Problem beim Kompilieren(der ist überflüssig). Für mich ist nur fraglich wieso der Kompiler macht keine Problemme bei den catch-blöcken: Exception,Throwable? In meinem try-block werfe ich doch keine Exception oder Throwable.
Code:
public class SupExp {
	public final static synchronized strictfp void main(String... s) {
		try {
			throw new ArrayIndexOutOfBoundsException();
		} catch (RuntimeException e) {
			System.out.print("GotoA, ");
		} catch (NullPointerException e) {
			System.out.print("GotoB, ");
		} catch (Exception e) {
			System.out.print("GotoC, ");
		} catch (Throwable e) {
			System.out.print("GotoD, ");
		}
	}
}
 
Da NPE eine RuntimeException ist, wird der Block nie erreicht, da der RuntimeExeption-Block alles abfängt.

Ändere die Reihenfolge und es sollte gehen:
Java:
} catch (NullPointerException e) { // NPE zuerst prüfen
  System.out.print("GotoB, ");
} catch (RuntimeException e) { //Dann alle Runtime Exceptions
  System.out.print("GotoA, ");
} catch (Exception e) {
  System.out.print("GotoC, ");
} catch (Throwable e) {
  System.out.print("GotoD, ");
		}
 
Schau dir die Vererbungshierarchie von Exceptions an, dann sollte dir das klarer werden.
Das du bei "Throwable" und "Exception keinen Fehler bekommst liegt einfach an der Vererbungshierarchie

Je spezifischer eine Exception ist um so weiter oben sollte deren catch-Block stehen.

Beispiel:
Folgende Methode ist gegeben
Java:
public void doSomething() throws NullPointerException, IllegalArgumentException {}

Nun kannst du es dir einfach machen in dem du einen allgemeinen catch-Block definierst
Java:
public void nope() {
   try {
      doSomething();
   } catch(Exception ex) {
      // handle Exception
   }

Aber es gibt auch den Fall das du eine Exception spezieller behandeln willst

Java:
public void nope() {
   try {
      doSomething();
   } catch(NullPointeException npex) {
      // error handling
   } catch(Exception ex) {
      // handle Exception
   }

Würdest du die Blöcke umdrehen hättest du wieder einen Compiler Fehler da der "Exception" catch Block schon alles behandeln würde und der andere somit nie zum Zug kommt.
 
Zuletzt bearbeitet:
Sorry aber eine Nullpointer Exception abzufangen ist doch totaler Mist.

Entweder man haut das Dingen um einen großen Block rum und hat dann keine Ahnung was eigentlich geknallt ist und wie man damit umgehen soll oder man hat eh nur ein paar wenige Punkte wo es knallen könnte und man kann an den Stellen entsprechend ein if(x!=null) machen und genau diesen Fehler geziehlt behandeln.
Mal ganz davon abgesehen, dass eine NPE immer ein Fehler des Programmierers ist und man diesen schon zur Entwicklungszeit beheben sollte und nicht zur Runtime.


Für mich ist sowas immer wie ein Breitband-Antibiotikum bei einer Grippe zu verschreiben.

Gruß

Claus
 
Zuletzt bearbeitet:
Ja Thallius NPE fangen ist zwar wirklich unsinnig. Habe es selbst noch nie gesehen das es Sinn machen würde, ob es wirklich gar keinen Sinn macht ist die andere Frage 😉

Aber es ging in diesem Beispiel grundsätzlich um verschieden spezifische catch-Blöcke und deren Reihenfolge.
 
In diesem Fall werden die catch-blöcke: RuntimeException, Exception, Throwable nie erreicht. Wieso gibt es von dem Kompiler keine Kompilierungsfehler, dass die Blöcke überflüssig sind und nie erreicht werden? Ich weiß dass Throwable ist der oberste Interface über Exception und RuntimeException.

Code:
public class SupExp {
	public final static synchronized strictfp void main(String... s) {
		try {
			throw new ArrayIndexOutOfBoundsException();
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.print("GotoA, ");
		} catch (RuntimeException e) {
			System.out.print("GotoB, ");
		} catch (Exception e) {
			System.out.print("GotoC, ");
		} catch (Throwable e) {
			System.out.print("GotoD, ");
		}
	}
}
 

Zurück
Oben