Es gibt viele ausgezeichnete Antworten, die die unglücklichen Symptome abdecken. Daher nullmöchte ich ein alternatives Argument vorlegen : Null ist ein Fehler im Typensystem.
Der Zweck eines Typensystems besteht darin, sicherzustellen, dass die verschiedenen Komponenten eines Programms richtig zusammenpassen. Ein gut geschriebenes Programm kann nicht "von der Stange kommen" undefiniertes Verhalten erkennen.
Stellen Sie sich einen hypothetischen Java-Dialekt oder eine beliebige statisch typisierte Sprache vor, in der Sie die Zeichenfolge "Hello, world!"jeder Variablen eines beliebigen Typs zuweisen können :
Foo foo1 = new Foo(); // Legal
Foo foo2 = "Hello, world!"; // Also legal
Foo foo3 = "Bonjour!"; // Not legal - only "Hello, world!" is allowed
Und Sie können Variablen wie folgt überprüfen:
if (foo1 != "Hello, world!") {
bar(foo1);
} else {
baz();
}
Daran ist nichts unmöglich - jemand könnte eine solche Sprache entwerfen, wenn er möchte. Der spezielle Wert muss nicht sein "Hello, world!"- es hätte die Zahl 42, das Tupel (1, 4, 9)oder sagen wir, sein können null. Aber warum würdest du das tun? Eine Variable vom Typ Foosollte nur Foos enthalten - das ist der springende Punkt des Typsystems! nullist nicht Foomehr als es "Hello, world!"ist. Schlimmer noch, es nullgibt keinen Wert irgendeiner Art und Sie können nichts damit anfangen!
Der Programmierer kann niemals sicher sein, dass eine Variable tatsächlich a enthält Foo, und das Programm kann es auch nicht. Um ein undefiniertes Verhalten zu vermeiden, müssen die Variablen überprüft werden, "Hello, world!"bevor sie als Foos verwendet werden. Beachten Sie, dass das Ausführen der Zeichenfolgenprüfung im vorherigen Snippet nicht die Tatsache verbreitet, dass foo1 wirklich ein Foo- barwahrscheinlich auch eine eigene Prüfung hat, nur um sicherzugehen.
Vergleichen Sie dies mit der Verwendung eines Maybe/ Option-Typs mit Mustererkennung:
case maybeFoo of
| Just foo => bar(foo)
| Nothing => baz()
Innerhalb der Just fooKlausel wissen sowohl Sie als auch das Programm, dass unsere Maybe FooVariable wirklich einen FooWert enthält - diese Informationen werden in der Aufrufkette weitergegeben und barmüssen nicht überprüft werden. Da Maybe Fooes sich um einen anderen Typ handelt Foo, sind Sie gezwungen, mit der Möglichkeit Nothingumzugehen , die er enthalten könnte NullPointerException. Sie können viel einfacher über Ihr Programm nachdenken, und der Compiler kann Nullprüfungen auslassen, wenn er weiß, dass alle Variablen des Typs Footatsächlich Foos enthalten . Jeder gewinnt.