Forum: PC-Programmierung Java-API-Kontract: Muss Implementierung eine NPE bei null werfen?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Achim H. (anymouse)


Lesenswert?

ich kenne mich schon etwas in Java aus.

Im Moment stolpere ich gerade über ein Update von Saxon-9.4 zu 9.8 bei 
der Implementierung der Methode 
javax.xml.transform.Transformer#setParameter .

Die Klasse "javax.xml.transform.Transformer" ist ein Interface und 
Bestandteil der API. Die eigentlichen Implementierungen sind häufig von 
Drittherstellern.

Java-Doc findet man hier:

https://docs.oracle.com/javase/7/docs/api/javax/xml/transform/Transformer.html#setParameter(java.lang.String,%20java.lang.Object)

Die Beschreibung für den Parameter "value" sagt:

"The value object. This can be any valid Java object. It is up to the 
processor to provide the proper object coersion or to simply pass the 
object on for use in an extension."

Es gibt eine Exception-Beschreibung

"Throws:  NullPointerException - If value is null."


DIE EIGENTLICHE FRAGE;

Kann man daraus schließen, dass bei Wert "null" JEDE Implementierung 
IMMER eine NullPointerException werfen MUSS (falls nicht, kann man dies 
als Bug ansehen), oder bedeutet dies nur, dass WENN die Implementierung 
null als Wert ablehnt, DANN muss sie dies mit einer NullPointerException 
tun?



Es geht mir hierbei nicht im die Quirks bestimmter Implementierungen, 
sondern die Interpretation der offiziellen Java-Dokumente. Und ich will 
auch keinen Transformer bauen, sondern nur einen nutzen. Hier ist das 
Verhalten aber für unterschiedliche Versionen verschieden.

von Cyblord -. (Gast)


Lesenswert?

Achim H. schrieb:
> Es gibt eine Exception-Beschreibung
>
> "Throws:  NullPointerException - If value is null."

Es ist eindeutig beschrieben. null => Exception, keine Ausnahme von der 
Ausnahme

von Wühlhase (Gast)


Lesenswert?

Ich les das auch so wie Abradolf: Laut Dokumentation ist bei einer 
Übergabe von Null eine Exception zu erwarten.

Freilich kann jemand, der das Interface implementiert hat, theoretisch 
davon abweichen, Null akzeptieren und irgendeinen Standardwert 
zurückliefern, also niemals eine Exception werfen. Damit bewegt er sich 
aber außerhalb der Spezifikation.
Gerade wenn die Implementierung von Dritten kommt würde ich mich nicht 
unbedingt darauf verlassen daß die Exception wirklich in jeder 
Implementierung kommt, also z.B. Prüfungen darauf aufbauen und deren 
Ergebnisse ernsthaft nutzen. Wer weiß, wer die Doku da mißversteht bzw. 
das eher als entbehrliche Option ansieht.

Ob man das schon als Bug ansehen kann weiß ich nicht, aber eine 
Abweichung von der Dokumentation ist es allemal.

von Achim H. (anymouse)


Lesenswert?

Kleiner Nachklapp: An anderen Stellen wird in der Parameterbeschreibung 
explizit erwähnt, dass der Parameter nicht null sein soll. Das wäre also 
überflüssig?

von Kaj (Gast)


Lesenswert?

Achim H. schrieb:
> Kleiner Nachklapp: An anderen Stellen wird in der Parameterbeschreibung
> explizit erwähnt, dass der Parameter nicht null sein soll. Das wäre also
> überflüssig?
Das kommt darauf an, wie du entwickelst (Design by contract). Es gibt 2 
Moeglichkeiten:
- Der Aufrufer muss sicherstellen, dass der Parameter nicht null ist 
(Beispiel aus C: Functionen wie strcpy)

- Der Aufgerufene muss sich um den Fall kuemmern, dass der Parameter 
null ist

Wenn es da so steht, wie du sagst, dann muss der Aufrufer fuer die 
Korrektheit der Parameter sorgen. Trotzdem solltest du dir ueberlegen, 
was deine Funktion macht, wenn da doch mal ein null oder ein anderer 
ungueltiger Wert kommt. In C fuehrt sowas regelmaessig zu 
Bufferoverflows, Programmabstuertzen und Sicherheitsluecken.

von Thorben R. (camyono)


Lesenswert?

Solange die Implementierung nicht überschrieben wird, gilt immer die 
Ableitung der Basis-Klasse.
1
public class BaseWithNPE {
2
  public void myCoolMethod(String abc) {
3
    if (abc == null) {
4
      throw new NullPointerException("abc == null");
5
    }
6
  }
7
  
8
  public class IDontNeedNPE extends BaseWithNPE {
9
     @Override
10
    public void myCoolMethod(String abc) {
11
      if (abc == null) {
12
        System.out.println("abc ist null aber keine NPE");
13
      }
14
      // No superclass call
15
      //super.myCoolMethod(abc);
16
    }
17
  }
18
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.