null/NullPointerException in anderen Programmiersprachen: Ruby, nil, Scala, Option, None, Some

Ist Java eine pure objektorientiere Programmiersprache? Nein, da Java einen Unterschied zwischen primitiven Typen und Referenztypen macht. Nehmen wir für einen Moment an, dass es primitive Typen nicht gibt. Wäre Java dann eine reine objektorientierte Programmiersprache, bei der jede Referenz ein pures Objekt referenziert? Die Antwort ist immer noch nein, da es mit null etwas gibt, mit dem Referenzvariablen initialisiert werden können, aber was kein Objekt repräsentiert und keine Methoden besitzt. Und das kann bei der Dereferenzierung eine NullPointerException geben.

Neue Programmiersprachen gehen da etwas andere Wege und null-Referenzierungen sind nicht möglich. In der Sprache Ruby zum Beispiel ist immer alles ein Objekt. Wo Java mit null ein „nicht belegt“ ausdrückt, macht das Ruby mit nil. Der feine Unterschied ist, dass nil ein Exemplar der Klasse NilClass ist, genau genommen ein Singleton, was es im System nur einmal gibt. nil hat auch ein paar öffentliche Methoden wie to_s (wie Javas toString()), was dann einen leeren String liefert. Mit nil gibt es keine NullPointerException mehr, aber natürlich immer noch einen Fehler, wenn auf diesem Objekt vom Typ NilClass eine Methode aufgerufen wird, die es nicht gibt.

In Objective-C, der Standardsprache für iPhone-Programme, gibt es das Null-Objekt nil. Üblicherweise passiert nicht, wenn eine Nachricht an das nil-Objekt gesendet wird; die Nachricht wird einfach ignoriert.[1] Es gibt Programmiersprachen, die noch etwas anders an das null-Problem herangehen. Bei der JVM-Sprache Scala gibt es für den Wert null einen eigenen Typ, nämlich Null. (Null erbt von AnyRef – was wiederum von Any erbt, dem absoluten Basistyp – und Null hat sogar mit Nothing einen Untertyp). Allerdings wird Scalas null nicht so wie Rubys null genutzt sondern entspricht Java null: Der Versuch, eine genullte Variable zu dereferenzieren, führt zu einer NullPointerException. Anders gesagt: Scala führt für null einen Typ ein, aber eine NullPointerException ist immer noch nicht passé. Statt aber in Scala null zurückzugeben, nutzen Programmierer etwas anderes: eine Option. Die Klasse Option repräsentiert optionale Werte und kommt in zwei Ausprägungen: Some und None (entspricht Rubys nil). Statt dass wie in Java eine Methoden eine Referenz direkt zurückgibt, geben Scala-Methoden etwas vom Typ Option zurück, und das heißt, entweder ein None- oder Some-Objekt. Das Some-Objekt ist ein Behälter und speichert die eigentliche Referenz. Eine Methode mit Option-Rückgabe sieht etwa so aus: if ( WertUngleichNull ) Some(Wert) else None. Mit dem parametrisierten Konstruktor Some(Wert) kommt der Wert in das Some-Objekt. Empfängt der Aufrufer die Rückgabe, kann er am Typ erkennen, ob die Operation erfolgreich war oder nicht. Das ist jedoch nicht, wie eine Option üblicherweise in Scala eingesetzt wird. Denn Option-Objekte (und somit Some oder None) besitzen eine Methode getOrElse(), sodass sich für eine Rückgabe result vom Typ Option schreiben lässt: result.getOrElse(alternativerWert). Repräsentiert result ein Some-Objekt, so liefert die Implementierung von getOrElse() den gespeicherten Wert, ist es None, so liefert die Implementierung das Argument als Rückgabe. Spontan hört sich das jetzt noch nicht so wahnsinnig innovativ an, aber interessant wird die Option durch die Tatsache, dass Scala sie an verschiedenen Stellen intern in den Klassenbibliotheken einsetzt. Das liegt dran, dass die Option-Klasse an die 30 Methoden deklariert und viele der Methoden etwa bei Operationen auf Datenstrukturen aufgerufen werden. Wenn zum Beispiel auf allen Elementen der Liste eine Transformation durchgeführt werden soll, und ein None-Objekt befindet sich in der Liste, passiert beim Aufruf der Transformationsmethoden auf dem None-Objekt nichts, denn dort ist die Implementierung einfach leer.


[1] Es gibt auch Compiler wie der GCC, der mit der Option -fno-nil-receivers dieses Verhalten abschaltet, um schnellere Maschinencode zu erzeugen. Denn letztendlich muss in Maschinencode immer ein Test stehen, der auf 0 prüft.

Ähnliche Beiträge

Veröffentlicht in Insel

4 Gedanken zu “null/NullPointerException in anderen Programmiersprachen: Ruby, nil, Scala, Option, None, Some

  1. Ist es denn jetzt Sinnvoll ein Singleton-Null-Objekt zu haben im Gegensatz zu einem Java-„null“?
    Bzw. gibt es in der alltäglichen Programmierung einen Vorteil wenn man beispielsweise ein if(returnValue.equals(Nil.instance()) anstatt eines if(returnValue == null) schreibt?

    Die Sache mit den Options klingt interessant, aber das könnte man ja auch in Java nachbauen. Beispielsweise mit einem parametrisierten Typ. Man müsste es eben nur konsequent einsetzen (die Collection-Klassen müssten wohl auch irgentwie nachgebildet werden…).
    interface Options {
    T getOrElse(T v);
    }
    class Some implements Options {
    private T value;

    public Some(T theValue) {
    this.value = theValue;
    }

    public T getOrElse(T v) {
    return this.value;
    }
    }
    class None implements Options {
    public T getOrElse(T v) {
    return v;
    }
    }

    Hier aber auch wieder die Frage: Ist eine solche Vorgehensweise besser?

  2. Irgentwie fehlen im obigen Beispielcode die Parametertypen der Klassen in spitzen Klammern.

    interface Options[T] {
    class Some[T] implements Options[T] {
    class None[T] implements Options[T] {

  3. Ich habe das nicht geschrieben, weil an der Stelle im Buch dem Leser Generics noch nicht bekannt sind.

    Auf der anderen Seite ist das komplizierter Stuff, sodass ich den Kommentar verschieben werden.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert