Referenceparameter auf null Prüfen?
-
Hallo zusammen,
ich wollte mal nachfragen wie man das in Java macht. In C++ muss ich ja nur Pointer auf 0 Testen, aber in Java sind ja alle nicht Primitivendatentypen Referencen und dann müsste ich die doch alle auf null Testen. Ist das nicht ziemlich langsam oder wird das weg optimiert?
Gruß, Daniel_S
-
Viele Methoden geben garnicht erst Null zurück, sondern werfen ne Exception, wenn was nicht funktioniert hat, also brauchst du da schon mal garnicht auf Null prüfen. Und wirklich viel Zeit braucht das auch nicht.
-
Die primitiven Datentypen übergibt man in Java gerade nicht per Referenz.
Objekte übergibt man per Referenz. Ob Du die auf null prüfen musst, hängt vom Einzelfall ab.
1. Wenn eine Methode private ist und somit ausschließlich klassenintern genutzt wird, dann bieten sich eher Assertions an, um die Methodenparameter den jeweils erlaubten Wertebereich hin zu überprüfen. Damit sind auch Checks bezüglich null gemeint. Ebenso verhält es sich mit der Überprüfung von Zwischenergebnissen innerhalb von Methoden. Auch hier sind in erster Linie Assertions angesagt. Assertions kann man beim Start der virtuellen Maschine an- und ausschalten. Wenn sie ausgeschaltet sind, dann kosten sie gar nichts.
2. Wenn Methoden von Orten außerhalb einer Klasse genutzt werden können, wenn sie also zum Beispiel public sind, dann bieten sich Checks bezüglich des Wertebereichs genau dann an, wenn ein falscher Wert (zum Beispiel null, wenn null nicht erlaubt ist) nicht sofort jenseits so eines Checks auffallen würde. Wenn Du also ein Objekt übergibst und dann sofort eine Methode des Objekts aufrufst, dann ist ein vorheriger Check auf null nicht besonders sinnvoll, da beim Methodenaufruf eh eine NullPointerException fliegen würde.
3. Somit sind derartige Checks eigentlich nur an den Stellen sinnvoll, an denen ein falscher Wert eines Parameters nicht sofort auffallen würde. Zum Beispiel wenn ein Objekt in irgendeiner Datenstruktur gespeichert wird und erst später darauf zugegriffen wird.
...IMHO.
Wenn Du überall ein
if(myParameter == null) throw new IllegalArgumentException("myParameter is null");
hinschreibst, dann kostet das natürlich Zeit. So ein Check wird AFAIK nicht wegoptimiert. Vermutlich ist das auch gar nicht möglich. Die Frage ist halt, an welchen Stellen Du so etwas machst. Relevant ist so eine Zeitverlust nur dort, wo eine Methode sehr oft aufgerufen wird und die Methode selbst kaum etwas macht. Im Zweifelsfall muss man da aber eben auch mal in den sauren Apfel beißen und solche Checks machen. Zum Beispiel wenn man eine Datenstruktur programmiert, die keine Nullobjekte aufnehmen können soll.
Es gibt auch statischer Checker, die begrenzt im statischen Zusammenhang checken können, ob eine Variable null sein kann. Da müsstest Du mal im Netz suchen, ob Du soetwas findest. Ich meine so etwas wie den "Extended Static Checker for Java". Allerdings weiß ich bei dem nicht, ob es sich noch um ein aktuelles Tool handelt.
-
sofa schrieb:
Viele Methoden geben garnicht erst Null zurück, sondern werfen ne Exception, wenn was nicht funktioniert hat, also brauchst du da schon mal garnicht auf Null prüfen. Und wirklich viel Zeit braucht das auch nicht.
Das finde ich nur unter gewissen Umständen sinnvoll. Erstmal sollte eine Methode komplett definiert sein. Damit meine ich, dass klar sein muss, welche Werte die Methodenparameter haben dürfen. Und wenn die Parameter erlaubte Werte haben, dann soll die Methode auch ein definiertes Ergebnis zurückliefern. Und das ist keine Exception. Exceptions sind eigentlich für 2 Fälle gedacht:
1. RuntimeExceptions sind gedacht, um Programmierfehler an der Schnittstelle zum jeweiligen Codeabschnitt abzufangen. Vor allem, wenn eine Methode mit nicht erlaubten Parametern aufgerufen wird, sollte man eine entsprechende RuntimeException schmeißen. Zum Beispiel eine IllegalArgumentException. Für RuntimeExceptions baut man normalerweise keine try-catch-Blöcke. Wie will man auch sinnvoll auf einen Programmierfehler reagieren? Einige Ausnahmen gibt es von dieser Regel natürlich. Zum Beispiel wenn irgendeine API keine Möglichkeit bietet, entsprechende Checks sinnvoll jenseits von vom Check auf den Wurf einer entsprechenden Exception zu machen.
2. Exceptions, die auf try-catch-Blöcke angewiesen sind, nutzt man nur dann, wenn etwas jenseits des Programms zu einer Ausnahmesituation führt. Ein Beispiel dafür ist die Maus, die das Netzwerkkabel durchbeißt. Auf so etwas kann man unter Umständen reagieren und dem Nutzer wenigstens eine aussagekräftige Fehlermeldung geben: "Dateiübertragung klappt nicht". Vielleicht kann man sogar noch besseres machen. Zumindest ist das etwas, mit dem der Nutzer etwas anfangen kann. Da ist offensichtlich etwas kaputt, was nichts mit dem Programm zu tun hat. Bei einem Programmierfehler kann man hingegen nur ausgeben: "Dieses Programm funktioniert mal gar nicht! Ätsch!". Damit ist dem Nutzer kein bischen geholfen.
Trotz allem gibt es oft Situationen, in denen man naiv schnell mal null zurückgibt, etwas anderes aber unter Umständen sinnvoller wäre. Zum Beispiel wenn eine Methode eine Datenstruktur zurückgibt. In so einem Fall kann eine leere Datenstruktur möglicherweise sinnvoller als null sein.
-
Ich meine nur die Returnwerte von Methoden. Wenn du z.B. keine DB-Connection aufbauen kannst, wird eine Exception geworfen und nicht NULL zurück gegeben, dann brauchst du die Connection auch nicht auf Null prüfen
-
Danke schön, das hat mir schon sehr geholfen.
-
Gregor schrieb:
Objekte übergibt man per Referenz.
Nicht ganz. Zumindest nicht im Sinne von C++.
http://www.javaranch.com/campfire/StoryPassBy.jsp
-
[ Ergänzung zum Beitrag von Dasd: ]
In java existiert nur call-by-value.
D.h.:
--> Bei ADT wird eine Reference übergeben, die kopiert wird --> Hat dann also 2 Referencen auf dasselbe Objekt.--> Bei vordefinierten Datentypen wird die Variable aber wirklich kopiert --> Hat dann also 2 Variablen mit demselben Inhalt.