# explizit NullPointerException werfen



## diggaa1984 (1. Apr 2009)

hallo, 

ich hab grad folgendes eingebaut:
[HIGHLIGHT="Java"]
//m und v sind strings
if ((m == null) || (v == null))
			throw new NullPointerException();[/HIGHLIGHT]

und mich im gleichen Moment gefragt ob es überhaupt Sinn macht jemals NPE's selbst zu werfen, denn schliesslich sorgt die Verarbeitung der Variablen ja schon dafür das einem NPE's um die Ohren fliegen wenn was nicht stimmt. Warum sollte ich also selbst noch eine werfen, wenn bei der erst-besten String-Operation eh eine geworfen wird ???:L Wenn auf etwas Verlass ist, dann auf diese Expception


----------



## tfa (1. Apr 2009)

Ja, das kannst du dir schenken, wenn in der selben Methode noch auf die Objekte zugriffen wird und die Exception automatisch  fliegt. Falls nicht, muss man eben nachhelfen und sie selbst werfen.


----------



## maki (1. Apr 2009)

NPE kann und soll man selber werfen, allerdings (wie alle Exeptions) mit einer aussagekräftigen Message.
Ausserdem sollten alle Exceptions die eine Methode werfen kann in der JavaDoc dazu dokumentiert sein.


----------



## Verjigorm (1. Apr 2009)

Kannst z.B. ein aussagekräftiges Kommentar mitgeben


----------



## diggaa1984 (1. Apr 2009)

tfa hat gesagt.:


> Ja, das kannst du dir schenken, wenn in der selben Methode noch auf die Objekte zugriffen wird und die Exception automatisch  fliegt. Falls nicht, muss man eben nachhelfen und sie selbst werfen.


hm ob es einen nun in der Methode raushaut oder eine später, macht ja kaum nen Unterschied, aber man kann natürlich dem Nutzer der Klasse zu liebe das ganze an der Wurzel ausgeben und nich 3 Stellen später. Ist das die Intention?



Verjigorm hat gesagt.:


> Kannst z.B. ein aussagekräftiges Kommentar mitgeben



in meinen augen der einzig brauchbare grund 

konkret sieht das grad mal so aus:
[HIGHLIGHT="Java"]#
public void addRule(String m, String v) throws BadGrammarException {
		if ((m == null) || (v == null))
			throw new NullPointerException();

		if (m.equals(v))
			throw new BadGrammarException("The rule: " + m + " = " + v + "does not hold the " +
										  "specification for CNF-notation.");

		v = v.trim();
		extractTerminal(v);
		addNonTerminal(m);

		rules.get(m).set(0, v);
	}//addRule[/HIGHLIGHT]


----------



## tfa (1. Apr 2009)

Ich find bei NPEx eine Message ziemlich überflüssig. Was kann schon groß passiert sein? Irgendeine Referenz war null. Datei und Zeilennummer steht im Stacktrace. Zur Not gibt es Debugger und Breakpoints.



diggaa1984 hat gesagt.:


> hm ob es einen nun in der Methode raushaut oder eine später, macht ja kaum nen Unterschied, aber man kann natürlich dem Nutzer der Klasse zu liebe das ganze an der Wurzel ausgeben und nich 3 Stellen später. Ist das die Intention?


Exceptions sollten so früh wie möglich fliegen. Das macht die Fehlersuche einfacher.


----------



## faetzminator (1. Apr 2009)

tfa hat gesagt.:


> Ich find bei NPEx eine Message ziemlich überflüssig. Was kann schon groß passiert sein? Irgendeine Referenz war null. Datei und Zeilennummer steht im Stacktrace. Zur Not gibt es Debugger und Breakpoints.


Ich finde das überhaupt nicht überflüssig, man sollte eine NullPointerException mit einem Text wie "kein Parameter darf null sein" werfen. Denn, wird eine NPE ohne Text geworfen, gehe ich davon aus, dass dies ein Programmierfehler in dieser Methode ist.


----------



## diggaa1984 (1. Apr 2009)

faetzminator hat gesagt.:


> Ich finde das überhaupt nicht überflüssig, man sollte eine NullPointerException mit einem Text wie "kein Parameter darf null sein" werfen. Denn, wird eine NPE ohne Text geworfen, gehe ich davon aus, dass dies ein Programmierfehler in dieser Methode ist.



das ist das letzte wovon ich ausgehe


----------



## maki (1. Apr 2009)

NPEs deuten eigentlich immer auf einen Programmierfehler.

Die NPE an sich & die Message sind imho bessere Mittel zur Fehlersuche als der Debugger 
Aber wie bereits gesagt, unbedingt in die JavaDoc aufnehmen.


----------



## diggaa1984 (1. Apr 2009)

ja javadoc steht ja ausser frage, das weiss ich


----------



## faetzminator (1. Apr 2009)

Ist halt ansichtssache - und kommt darauf an wer deinen Code (z.B. als lib) weiterverwendet...


----------



## tfa (1. Apr 2009)

Freifliegende NPEx sind sowieso Programmierfehler, ob nun in der aufgerufenen oder aufrufenden Methode...

Parameterchecks kann man einfacher mit asserts machen.


----------



## SlaterB (1. Apr 2009)

nie NullPointerException selber werfen,
wenn nicht assert, dann IllegalArgumentException oder sonst was sinnvolles, NullPointerException ist reserviert



faetzminator hat gesagt.:


> Ich finde das überhaupt nicht überflüssig, man sollte eine NullPointerException mit einem Text wie "kein Parameter darf null sein" werfen.


-> IllegalArgumentException 


> Denn, wird eine NPE ohne Text geworfen, gehe ich davon aus, dass dies ein Programmierfehler in dieser Methode ist.



JEDE NPE sollte so sein bzw. KEINE mit Text


----------



## maki (1. Apr 2009)

>> Parameterchecks kann man einfacher mit asserts machen. 

Soll man aber nicht 

Einmal sind sie nicht so aussagekräftig weil immer nur derselbe AssertError geworfen wird, dann ist es nicht sicher ob asserts überhaupt aktiviert sind.


----------



## tfa (1. Apr 2009)

Okay, assertions lieber doch nur für Vor- und Nachbedingungen (obwohl man Parametergültigkeit auch als Vorbedingung ansehen kann). Es kommt wohl auch darauf an, ob man sie in einer wiederverwendbaren Library einbaut, oder in einem geschlossenen Modul, das man vollständig durchtesten kann.


----------



## maki (1. Apr 2009)

Assertions sind imho eher etwas für Unittests, nämliuch die assertXXX Methoden, diese können auch nicht abgeschaltet werden wie die Standard Java Asserts.

Diese mögliche abschalten der Asserts macht sie imho unzuverlässig.


----------



## SlaterB (1. Apr 2009)

man könnte da bisschen unterscheiden zwischen reinen Programmier-Checks und Test auf User-Eingaben, DB-Results usw.,
letztere können und sollen auch zur Laufzeit aktiv werden und fachliche Fehler prüfen,

erstere dienen nur zur Absicherung in der Programmierphase, um tatsächlich eher inhaltslose NullPointerException zu ersetzen,
wenn diese fehlen, dann dürfte das Programm trotzdem eine Exception werfen


----------



## Ebenius (1. Apr 2009)

tfa hat gesagt.:


> Parameterchecks kann man einfacher mit asserts machen.


 Nein! Hilfe! Parameterchecks in privaten Methoden kann man mit _assert_s machen. In einer von außen sichtbaren Schnittstelle haben _assert_s zur Parameterprüfung nichts verloren! Erstens sind sie (pro package oder insgesamt) abschaltbar, im Standardfall sind sie nichtmal eingeschaltet und zweitens werfen _assert_s keine Exceptions sondern Errors und damit ist es mehr oder minder verboten die Fehler sinnvoll zu behandeln. Siehe Sun Guide: Programming with Assertins.

Um Parameter zu überprüfen sollte man übrigens stets NullPointerException ggü. IllegalArgumentException abwägen. Meist gewinnt letztere. Faustregel: Wenn aus der Methode vollkommen einwandfrei ersichtlich ist, dass die Methode mit _null_-Argument keinen Sinn ergibt, so kann man bei _null_ eine NullPointerException werfen. In jedem anderen Fall sollte man sich für IllegalArgumentException entscheiden.

Und nun noch zur eigentlichen Frage des Themas: Die NullPointerExceptions selbst zu werfen hat dann Sinn, wenn die NullPointerException ohnehin auftreten würde, vorher aber schon Dinge passiert sein würden die man rückgängig machen müsste. Beispiel: [HIGHLIGHT="Java"]void sendMeYourQuote(QuotationReceiver recv) {
  // throw NPE here, as our state would change and a quotation would
  // be created and calculated before NPE would be thrown
  if (recv == null) {
    throw new NullPointerException("recv is null");
  }

  final ProjectDetails pd = requestProjectDetails();
  final Quotation quote = createQuotation(pd);
  recv.receiveQuote(quote); // NPE would be thrown AFTER calculation
}[/HIGHLIGHT]
Ebenius


----------



## faetzminator (1. Apr 2009)

SlaterB hat gesagt.:


> -> IllegalArgumentException


Finde ich sinnvoll, sofern nicht null übergeben wird


----------



## schalentier (1. Apr 2009)

Bei uns sieht das in etwa so aus:


```
void sendMeYourQuote(QuotationReceiver recv) {
   if( isNotNull( recv ) ) {
      // ...
   } else {
      handleUnexpectedNull( "recv" );
   }
}
```

Das ganze kann man z.B. als Live Template (ka wie die Dinge in Eclipse heissen) speichern, dann reicht "inn" + Tab und obiger Code steht da.

Was handleUnexpectedNull genau macht, ist dann frei definiertbar. Z.B. ne NPE schmeissen (schlecht IMHO), IllegalArgumentException, auf Console schreiben, ins Logfile schreiben, etc.


----------



## faetzminator (1. Apr 2009)

ich finde diese if() { } else { } Verschachtelungen in einem solchen Fall schrecklich, wie wärs mit

```
void sendMeYourQuote(QuotationReceiver recv) {
   if(isNull(recv)) {
      handleUnexpectedNull( "recv" );
      return;
   }
   // ...
}
```


----------



## schalentier (1. Apr 2009)

Das wiederum finde ich schrecklich, da Methoden so mehrere "Exitpoints" haben. Aber is wohl Geschmackssache.


----------



## Ebenius (1. Apr 2009)

faetzminator hat gesagt.:


> ich finde diese if() { } else { } Verschachtelungen in einem solchen Fall schrecklich, wie wärs mit
> 
> ```
> void sendMeYourQuote(QuotationReceiver recv) {
> ...


Das finde ich wiederum grausam, weil es dem caller das Problem vorenthält. Der callee kann doch gar nicht wissen, wie der Fehler behandelt werden muss und genau darum geht es ja.

Ebenius


----------



## faetzminator (1. Apr 2009)

Ich ging davon aus, dass in handleUnexpectedNull() z.B. etwas geloggt und dann eine NullPointer geworfen wird --> das return; falls nichts geworfen wird...


----------



## tfa (1. Apr 2009)

faetzminator hat gesagt.:


> ich finde diese if() { } else { } Verschachtelungen in einem solchen Fall schrecklich, wie wärs mit [returns]


Das ist beides schrecklich. Exceptions sollen doch gerade dabei helfen, diese Unübersichtlichkeiten zu vermeiden.

Ich würde es so einfach so lösen:
[HIGHLIGHT="Java"]
/**
 * Mache irgendwas.
 * @param m das m (darf nicht null sein)
 * @param v das v (darf nicht null sein)
 * @throws NullPointerException wenn m oder v null sind
 * @throws BadGrammarException wenn sonstwas falsch läuft...
 */
public void addRule(String m, String v)  {
        v = v.trim();
        if (m.equals(v))
            throw new BadGrammarException("The rule: " + m + " = " + v + "does not hold the " +
                                          "specification for CNF-notation.");


        extractTerminal(v);
        addNonTerminal(m);

        rules.get(m).set(0, v);
    }[/HIGHLIGHT]
Das ist aber keine 1 zu 1 Umsetzung des Quellcodes aus Beitrag #5. Hier wird zuerst auf v getestet und es erst dann getrimmt. Möglicherweise ein Problem.


----------



## maki (1. Apr 2009)

Wenn die Prüfung der Paramter soviel Platz einnimmt/Umfangreich/Komplex ist, dann darf man sie auch ruhig in eine eigene Klasse auslagern.


----------



## diggaa1984 (1. Apr 2009)

ja da smit dem trim sollte ich vor das equals ziehen ^^

@maki ist das auf mein code bezogen!? .. respektive tfa's?


----------



## maki (1. Apr 2009)

Das war nicht auf irgendeinen code bezogen, sondern nur allgemeines blabla


----------



## diggaa1984 (1. Apr 2009)

wollt mich schon wundern


----------

