Moin moin, Am Saturday 27 December 2003 14:25 schrieb Bernhard Walle:
On Sat, 27 Dec 2003 at 14:10 (+0100), Andre Heine wrote:
Am Saturday 27 December 2003 13:42 schrieb Bernhard Walle:
[...]
Was ist den mit der berüchtigten "NullpointerException" in Java? Wird da nicht auf ein "nicht initialisiertes Objekt" zugegriffen?
Also greift da Java z.B. auf Speicher zu, der nicht initialisiert ist (oder noch nicht).
Du kannst eine Nullpointer-Exception in Java nicht mit einem Speicherzugriffsfehler in C/C++ vergleichen. Auf
Hmm...
uninitialisierte Objekte kann man in Java nicht zugreifen, da sowas bereits der Compiler überprüft.
Nun, ein "int" ist auch kein Objekt!
Bsp.:
// j hat irgendeinen Wert int i; if (j > 5) { i = 10; } System.out.println(i); // wird vom Compiler abgelehnt da potentiell // uninitialisiert
Wenn Du nun aber z.B. ein String-Objekt hast und diesen String mit etwas vergleichen möchtest. public class test { public static void main( String argv[] ){ // Dieser Code ist SUPERSCHLAMPIG und ein negativ Beispiel argv[1].equals("compse"); } } Hier meckert der Compiler definitiv nicht beim kompilieren! voodoo@yamato:~/java$ java test Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 at test.main(test.java:18) Hier ist mein Programm Hardcore ausgestiegen, würde ich die Exception fangen, läuft das Programm eben weiter. Auch wenn hier etwas sehr undefiniertes passiert ist... Das ist nach meiner Meinung ein Speicherzugrifffehler, weil ich auf ein Array Element zugreife das nicht existiert, bzw. der Bereich mir nicht gehört. Genau hier wird eine Exception geworfen damit das Programm noch weitermachen kann (wenn man sie den fängt). Darum habe ich meine obigen Aussagen getroffen, dass dazu eben "try/catch" benutzt wird.
Ein Nullzeiger ist kein uninitialisiertes Objekt. Es exisitert überhaupt kein Objekt, die Referenzvariable hat schlicht den Wert
Wenn das Objekt nicht existiert, darf ich auch nicht darauf zugreifen, d.h. ich habe auf Speicher zugegriffen, der sonstwem gehört. Ist diese Annahme falsch?
null wie in C++ ein Zeiger den Wert 0 (NULL) haben kann. Wenn Du in Java nativen Code hast gibt es auch hier das Problem eines Speicherzugriffsfehler. Die VM befindet sich dann in einem nicht definierten Status und das Programm sollte beendet werden.
Nun, vielleicht ist ein Segfault so schwerwiegend, das das Programm beendet werden muss. Das kann ich leider nicht sagen. Ich würde trotzdem den Aufruf der nativen Methode in "try/catch" Blöcke packen und es probieren *g*. Leider habe ich heute keine Zeit mehr um dafür mal etwas Beispiel Code zu produzieren... Das werd' ich morgen mal machen und meine Erkenntnisse posten.
In C++ greift man auf einen Speicherbereich zu, der vom Betriebssystem einem anderen Prozess zugeordnet wurde. Dies wird dann vom Betriebs- system mit einem SIGSEGV abgelehnt. Das Programm befindet sich dadurch in einem potentiell undefinierten Zustand, kann noch Aufräumarbeiten durchführen und hat sich dann zu beenden. Standardmäßig beendet es sich umgehend. Eine Ausnahme wird da an keiner Stelle geworfen.
In meinem C++ Buch steht wofür ich das "exception handling" nutzen kann. Zitat aus "C++ Einführung in die professionelle Programmierung", von Breymann, Hanser Verlag. - Division durch Null - Bereichsüberschreitung eines Arrays - Syntaxfehler bei Eingaben - Zugriffe auf nicht geöffnete Dateien - Fehlschlag bei der Speicherbeschaffung - Nichteinhaltung einer Vorbedingung einer Methode Ist den ein "Fehlschlag bei der Speicherbeschaffung" kein falscher Zugriff auf den Speicher (oder ist damit nur gemeint, das zuwenig Speicher vorhanden ist, vermutlich ja *g*). Die Bereichsüberschreitungen in Arrays zähle ich dazu. Nun gut, eval() war vielleicht keine gute Idee. Try & catch vielleicht auch nicht. Ich wollte eigentlich nur ausdrücken, das wenn Fehler im try Block auftauchen, eben der catch-Block ausgeführt wird. Das macht man eben um den Fehler eventuell zu beheben oder um wenigsten jemanden zubenachrichtigen ohne das Programm zu killen. Ciao Andre