Ich habe eine Klasse mit genau einem Konstruktor und unter anderem einem Cache als globale Variable.
Kann es irgendwelche Probleme geben, wenn ich die globale Variable direkt initialisiere oder ist das egal?
Ich nutze die erste Methode, seit ich einmal lange nach der Ursache einer NullPointerException suchen musste - ich hatte zuvor in einer Klasse letztere Methode verwendet und später einen weiteren Konstruktor hinzufügen müssen, wobei ich aber die Initialisierung meines Objektes vergaß (es war einfach der Standardkonstruktor, wurde vom Framework verlangt).
Initialisiere ich die Variable gleich bei der Deklaration, muss ich mich im Konstruktor nicht mehr darum kümmern - aus meiner Sicht einfacher, wenn man den Code dann u. U. umändern bzw. ergänzen muss.
Bei mir kommt es ganz auf den Variablentyp an, wenn ich z.B. einen Konstruktor für ein JFrame schreibe, tue ich erst
Java:
privateJLabel label =null;
aufrufen und dann im Konstruktor mit Werte füllen. Andere Dinge, z.B. Stringarrays (z.B. für JOptionPane Antwortmöglichkeiten), dann wie die erste Methode es sagt.
@Gastredner: Bei mir ist da nochnie ne Nullpointerexception aufgerufen worden?
> @Gastredner: Bei mir ist da nochnie ne Nullpointerexception aufgerufen worden?
was willst du denn damit sagen, was ist 'da'?
Gastredner hat eine klare Situation beschrieben, die 100% zu einer NPE führt (wenn man sie denn auch entsprechend hat..)
---------
= null;
empfehle ich persönlich nicht zu schreiben, einfach weglassen geht genauso und kann folgenden Effekt herbeiführen
(wenn auch in an sich fraglichen unsauberen Aufbau)
Java:
publicclassTest{publicstaticvoidmain(String[] args){newA();}}classAextendsB{privateString x;privateString y =null;publicA(){System.out.println("x: "+ x);System.out.println("y: "+ y);}publicvoidinit(){
x ="xxxxxxxxxx";
y ="yyyyyyyyyy";}}abstractclassB{publicB(){init();}publicabstractvoidinit();}
Mich würde auch der Unterschied interessieren zwischen beiden Methoden, wann wird das erste denn ausgeführt (Beim Laden der Klasse geht nicht, weil für jedes Objekt ne neue Map gebaut werden muss, also vor jedem Konstruktoraufruf?)
Ich würde die 2. Methode nutzen, muss dabei dann eben wirklich drauf achten das in jedem Konstruktor zu initialisieren (sonst fliegen wie oben erwähnt irgendwo mal die NPE ohne dass man den Fehler sofort sieht)
Erstmal danke an alle.
Den Code von SlaterB verstehe ich allerdings nicht:
Java:
classAextendsB{privateString x;privateString y =null;publicA(){System.out.println("x: "+ x);System.out.println("y: "+ y);}publicvoidinit(){
x ="xxxxxxxxxx";
y ="yyyyyyyyyy";}}
Würde dieser Code überhaupt kompilieren? x ist ja nicht initialisiert, denn init wird ja nicht garnicht aufgerufen.
Fehlt da vielleicht ein super(); im Konstruktor von A? Aber selbst wenn, können abstrakte klassen überhaupt Konstruktoren haben/aufrufen?
Auch das kommt mir irgendwie komisch vor, die Init ist ja abstrakt, wie soll man die da aufrufen können?
Ich probier das mal bei mir aus...
Edit: Also es funktioniert ja tatsächlich. Komisch, bei mir meckert das Java sonst immer rum wenn ich variablen aufrufe die nicht initialisiert wurden und will dann garnicht kompilieren. Und auch der Rest: Erstaunlich dass das geht, verstehe ich aber nicht ganz
Normal sollte man doch eh alles in einem(und zwar den am meisten Paramaterisiertesten ) initialisieren, dann hat man diese Probleme (Map nicht initialisiert) doch garnicht, wenn alle Anderen diesen schön aufrufen ?!
@kirdie
ist ein kompliziertes Beispiel mit mehreren Klassen, die per Vererbung durcheinander arbeiten,
muss du nicht verstehen,
jedenfalls gibts bei Klassenattributen kein 'nicht initialisiert', die sind immer null, 0 oder false wenn nicht anders angegeben,
das = null; kann man weglassen, bringt nichts, nur Probleme im Extremfall (wird erst nach Abschluss der Super-Konstruktoren ausgeführt)
Ich glaube Eclipse macht da Unterschiede bzgl Compilieren.
Eclipse gibt dir das als Warunung bzw. als Error aus weil es eben zu einen Fehler führen >kann<, nicht muss. Das Warning etc kann man in Eclipse einstellen.
Ich persöhnlich würde eine init() Methode bevorzugen, eben aus dem Grund, dass man neue Konstruktoren hinzufügt und sowas mal vergessen kann (mir auch schon passiert)
Auch wenn ich das nicht muss, würde mich das trotzdem interessieren
Vor allem, warum da anscheinend ein Konstruktor der Superklasse aufgerufen wird, ohne dass da ein Aufruf von super(); drin ist.
Ich habe eine Klasse mit genau einem Konstruktor und unter anderem einem Cache als globale Variable.
Kann es irgendwelche Probleme geben, wenn ich die globale Variable direkt initialisiere oder ist das egal?
ansonsten kann ich aus Erfahrung sprechen das der erste Konstrukt unter Eclipse läuft ... aber auf dem Root-Server kam nach X Monaten eine NullPointerException ;( ... und nun such mal den Fehler wieder mit Eclipse wo die Initialsierung funktioniert :autsch: