Stil - try, catch
-
interpreter schrieb:
Hi,
Deine Variante ist auf alle Fälle besser, als die Version von Kati. Exceptions sollte man auf jeden Fall vermeiden, da ihre Abarbeitung ca 1000Mal länger braucht als eine normale Anweisung. Die Logik "Wenn meine Referenz auf null zeigt, dann fang ich halt einfach die Nullpointer-Excetion" ist also ziemlich mieser Stil.
floin zahlreichen java-Büchern wird aber eigentlich was anderes geprädigt... oder ?! ... der Sinn der ganzen Sache ist, dass der Programmierer nicht an alles denken kann. In diesem Fall würde anscheinend jeder als erstes eine Verzweigung schreiben, um zu schauen, ob ein Objekt null ist bevor auf das Objekt zugegriffen wird... ist auch klar. Der Sinn der Sache ist aber, den Programmierer möglichst zu entlasten. In komplexen Programmen ist oft der Code nicht so überschaubar wie hier. Es können dann Fälle vorkommen, dass einfach irgendwo (wie hier) eine NullPointerExcpeiton auftritt. Daher dieser Gedanke. ... Außerdem wird konkret in diesem Programm der Socket 1x geschlossen... d.h. es handelt sich nicht um einen Code, der öfters ausgeführt wird. Daher kann man hier diesen Performance-Nachteil locker in Kauf nehmen. ... Ansonsten kommt es immer auf die Situation an.. wenn die Exceptions nicht "angebracht" sind, verzichtet man auf sie. Der Code wird durch sie aber oft sicherer und transparenter.
-
catch(NullPointerException e)
Die NullPointerException ist IMHO eine Exception, bei der es niemals so weit kommen sollte, dass man sie fangen muss, weil man eben nicht weiß ob das Objekt jetzt schon null ist oder nicht. Das sollte IMHO immer anders überprüft werden.
-
destruct0r schrieb:
Die NullPointerException ist IMHO eine Exception, bei der es niemals so weit kommen sollte, dass man sie fangen muss, weil man eben nicht weiß ob das Objekt jetzt schon null ist oder nicht. Das sollte IMHO immer anders überprüft werden.
jo... du hast vielleicht recht... das Überprüfen "ist ein objekt null?" gehört zu den grundlegendsten überhaupt. Ich finde es auch in Ordnung, dass man zuerst schaut, ob das Objekt überhaupt erzeugt wurde, bevor man mit ihm irgendetwas anstellt. Es schaut auch nicht besonders schön aus (catch(NullPointerException)). Es war auch nur ein Beispiel...
@destructor
Außerdem was hältst du von throws Klausel ? Ich denke, dass es (wenn Programme groß werden) ganz praktisch ist, eigene Exceptions zu schreiben und wenn Exception auftreten eigene Exceptions auszulösen. Ich habe damit eine sehr gute Erfahrung gemacht: die Exception können dann schön kategorisiert und geloggt werden. Besonders, wenn viele komplexe Klassen miteinander kommunizieren und große Datenbestände verwaltet werden. Diesen Ansatz finde ich gut.
-
destruct0r schrieb:
catch(NullPointerException e)
Die NullPointerException ist IMHO eine Exception, bei der es niemals so weit kommen sollte, dass man sie fangen muss, weil man eben nicht weiß ob das Objekt jetzt schon null ist oder nicht. Das sollte IMHO immer anders überprüft werden.
Dem stimme ich auch vollkommen zu.
@ Shade: Was mir an deinem Code noch auffällt ist, dass du z.B. eine Exception fängst, obwohl eine IOException geworfen wird. Man sollte NIE allgemein Exceptions fangen, sondern immer die speziellen Typen.
Ansonsten kann ich dir nur sagen, dass IO ein Gebiet ist, in dem Java sehr viel mit Exceptions arbeitet. In anderen Bereichen brauchst du bei weitem nicht so viele try-catch-Blöcke.
-
Gregor schrieb:
@ Shade: Was mir an deinem Code noch auffällt ist, dass du z.B. eine Exception fängst, obwohl eine IOException geworfen wird. Man sollte NIE allgemein Exceptions fangen, sondern immer die speziellen Typen.
Gibts da auch eine Erklärung dazu?
Ich fange Exception eigentlich deswegen, weil ich nicht auf die Ausnahme reagiere, sondern einfach nur e.getMessage() in ein Logfile schreibe.Ansonsten kann ich dir nur sagen, dass IO ein Gebiet ist, in dem Java sehr viel mit Exceptions arbeitet. In anderen Bereichen brauchst du bei weitem nicht so viele try-catch-Blöcke.
Ich habe kein Problem damit, wenn man viele try, catch schreiben muss. Nur ich war mir nicht sicher, ob man das auch wirklich so macht. Wie gesagt: in C++ ist es anders. Aber ich will ja nicht C++ in Java programmieren, sondern Java
Das
if(sock!=null) sock.close();
soll ich so lassen?
Mir persönlich dreht es bei einer NullPointerException den Magen um.
Btw:
verwendet man in Java auch ein... } catch(Exception e) { Log(e.getMessage()); throw e; //bzw. throw; falls es das gibt }
sprich: wirft man in Java auch mal ne Exception weiter, oder behandelt man immer alle Fehler so lokal wie möglich?
-
Außerdem was hältst du von throws Klausel ? Ich denke, dass es (wenn Programme groß werden) ganz praktisch ist, eigene Exceptions zu schreiben und wenn Exception auftreten eigene Exceptions auszulösen
Die throws-Anweisung ist ein Befehl wie andere in Java auch. Man wirft damit eben Exceptions, auch selbstgeschribene. Mir persönlich gefällt das Konzept der Exceptions gut. Man kann so dem Aufrufer genu mitteilen, was falsch gelaufen ist und wo das war...
-
Shade Of Mine schrieb:
Mir persönlich dreht es bei einer NullPointerException den Magen um.
[...]
sprich: wirft man in Java auch mal ne Exception weiter, oder behandelt man immer alle Fehler so lokal wie möglich?1. Mir dreht sich bei der NullPointerException auch der Magen um.
2. Man reicht Exceptions auch durchaus mit throws weiter, wenn man sie lokal nicht sinnvoll behandeln kann.Man fängt Exceptions nicht allgemein, weil es zu Fehlern führt, die auch noch schwer zu finden sind. Es kann ja auch mal vorkommen, dass eine Exception geschmissen wird, die eben nicht der Exception entspricht, die man an dieser Stelle erwartet.
-
Wieso schachtelt ihr try-catch-Blöcke? Das ist doch gerade der Vorteil gegenüber alten C-Programmen, die einen Fehler über den Returnwert angezeigt hatten. Dort hatte man diese Verschachtelungen wenn man mehrere Bedingungen hintereinander abfragen musste. In Java genügt ein try und alle Exceptions, die innerhalb des try-Blocks auftreten können, können durch sequentiell angegebene catch-Blöcke abgefangen werden.
-
CengizS schrieb:
Wieso schachtelt ihr try-catch-Blöcke?
Meinst du das hier ?
try { sock=new ServerSocket(port); while(true) { try { Socket client=sock.accept(); //hier wird dann mit dem socket gearbeitet, //ist aber unwichtig } catch(Exception e) { //fehler wird geloggt, sonst nix } } } catch(Exception e) { //fehler wird geloggt, sonst nix }
Offensichtlich will er nicht gleich in catch() der äußeren Schachtelung landen, sondern mit der Schleife weitermachen...
Wenn du das mit dem Schließen des Sockets meinst --> er schließt es innerhalb von finally (was ich auch richtig finde). Und da die Methode close() wiederum eine Exception auslöst (also die Signatur lautet ... throws IOException), ist er sogar gezwungen, sie abzufangen.
Oder was meinst du? Ist es schlecht, try-catch-Blöcke zu schachteln?
kati
-
Kati schrieb:
Offensichtlich will er nicht gleich in catch() der äußeren Schachtelung landen, sondern mit der Schleife weitermachen...
exakt.
denn wenn ein .accept() fehl schlägt, soll trotzdem weiter gelauscht werden - denn es ist ein server - da muss man immer connecten können.@CengizS:
Um ehrlich zu sein, mir gefallen diese vielen try, catch Blöcke auch nicht. Denn momentan besteht die Klasse aus mehr Fehlerabfangungen als sinnvollen Code. (wobei sie eben noch nicht fertig ist)Aber wie sieht die Alternative aus? Bisher dachte ich, in Java macht man es halt so...
Wenn man es anders auch machen kann, bzw. soll - nur her damit.
Ich versuche mich in Java gerade reinzufinden, nebenbei schau ich n bisschen in 'Thinking in Java' rein, weil ich 'Thinking in C++' recht gut fand.Gibt es eine Pflichtlektüre für Java? Sowas wie die Bücher von Scott Meyers in C++? Da Weihnachten ist, kann es durchaus auch ein Buch sein.
Vielen Dank!
-
Gibt es eine Pflichtlektüre für Java?
Nö, aber ein Pflicht-Tutorial: http://www.galileocomputing.de/openbook/javainsel3/index.htm