Variablendeklaration/-instanzierung

Hallo,

kann mir jemand sagen, was hier der Unterschied ist:

entweder so:

public class Test
{
Testklasse myTest = new Testklasse();
.
.

oder oben eben nur die Deklaration der Variable:

public class Test
{
Testklasse myTest;
.
.

und im Konstruktor dann

public Test()
{
myTest = new Testklasse();
}

Ein Freund meinte, in beiden Fällen würde beim Instanzieren eines Objektes Test auch eine eigene Instanz des Objektes Testklasse erzeugt.
In meinem Programm verhalten sich beide Varianten allerdings ein klein wenig anders (wäre jetzt ein wenig kompliziert zu erklären). Darum frag ich mich, wo nun der Unterschied ist?

Danke,
Chups

Moien

Das new klappt ohne irgendwelche Exceptions ?

Ein Freund meinte, in beiden Fällen würde beim Instanzieren
eines Objektes Test auch eine eigene Instanz des Objektes
Testklasse erzeugt.

Stimmt.

In meinem Programm verhalten sich beide Varianten allerdings
ein klein wenig anders (wäre jetzt ein wenig kompliziert zu
erklären).

Dann fang man an.

Darum frag ich mich, wo nun der Unterschied ist?

Das ist kein richtiger Unterschied. Nur wenn das new wegschlägt oder du ganz böse Dinge mit dem Classloader gemacht hast kann man die 2 Fälle unterscheiden.

cu

Hallo,

Moien

Das new klappt ohne irgendwelche Exceptions ?

Ja, es sind keinerlei Probleme aufgetreten.

In meinem Programm verhalten sich beide Varianten allerdings
ein klein wenig anders (wäre jetzt ein wenig kompliziert zu
erklären).

Dann fang man an.

Ok, ich versuchs mal.

ich habe:

1 Klasse „A“
1 Klasse B extends A

1 Klasse C
1 Klasse D extends C

so, nun hat die Klasse A eine Membervariable vom Typ D
und die Klasse C eine Membervariable vom Typ B.

Instanziere ich diese Membervariablen jeweils im Kontstruktor, komme ich z.B. beim Erzeugen eines Objektes A sofort in eine Schleife, denn es wird ja im Konstruktor von A ein Objekt D erzeugt, und im Konstruktor dessen Vaterklasse C wird ja wiederrum ein Objekt der Klasse B erzeugt, was wiederum bewirkt daß in dessen Vaterklasse A im Konstruktor wieder ein Objekt D erzeugt wird, usw. usf. :-/

Lustigerweise passiert das ganze nicht, wenn ich die Instanzierungen nicht im Konstruktor von A bzw. C mache, sondern oben im Deklarationsbereich.

Also eben:

public class A
{
D myD = new D();
.
.
usw.

Moien

1 Klasse „A“
1 Klasse B extends A

1 Klasse C
1 Klasse D extends C

so, nun hat die Klasse A eine Membervariable vom Typ D
und die Klasse C eine Membervariable vom Typ B.

Böser Design Fehler.

Instanziere ich diese Membervariablen jeweils im Kontstruktor,
komme ich z.B. beim Erzeugen eines Objektes A sofort in eine
Schleife

Das war klar.

Lustigerweise passiert das ganze nicht, wenn ich die
Instanzierungen nicht im Konstruktor von A bzw. C mache,
sondern oben im Deklarationsbereich.

Hast du 2 unterschiedliche Konstruktoren benutzt ?

Also einmal new A(); und einmal new A(parameter); ?

cu

Moien

1 Klasse „A“
1 Klasse B extends A

1 Klasse C
1 Klasse D extends C

so, nun hat die Klasse A eine Membervariable vom Typ D
und die Klasse C eine Membervariable vom Typ B.

Böser Design Fehler.

Ja, wenn ich es so mache, daß ich in diese Instanzierungs-schleife (also D und B jeweils im Konstruktor instanzieren) komme, schon.
Aber wenn ich die Objekte D und B z.B. nur in den Methoden instanzieren würde, wo ich sie verwende, dürfte das ja eigentlich kein Problem sein, oder?

Lustigerweise passiert das ganze nicht, wenn ich die
Instanzierungen nicht im Konstruktor von A bzw. C mache,
sondern oben im Deklarationsbereich.

Hast du 2 unterschiedliche Konstruktoren benutzt ?

Also einmal new A(); und einmal new A(parameter); ?

Nein, immer nur einen parameterlosen Konstruktor.

Danke,
Chups

Sorry, ich habe etwas übersehen.

In der Klasse C hatte ich bei der Deklaration/Instanzierung der Membervariable B noch ein „static“ davor stehen, und komplett darauf vergessen.
Darum ging das ganze dann auch soweit ohne Fehler.

Wenn ich das static wegnehme, komme ich wieder in die Schleife rein.

Ok, das heißt erstmal, daß die zwei Varianten in meiner Eingangsfrage wohl wirklich genau dasselbe tun.

Nun zum Rest:
Ist es auch noch ein Desingfehler, wenn ich wie schon erwähnt die beiden Membervariablen eben nicht global für die ganze Klasse gültig mache (durch Initalisierung z.B. im Konstruktor), sondern erst in den jeweiligen Methoden initialisiere?

Bzw. wäre es ok, so wie ich es eben schon probieren wollte, die beiden Variablen einfach static zu machen? Somit würde ja jeweils nur 1 Instanz bestehen, und ich käme in keine Instanzierungsschleifen.

Moien

Ist es auch noch ein Desingfehler, wenn ich wie schon erwähnt
die beiden Membervariablen eben nicht global für die ganze
Klasse gültig mache (durch Initalisierung z.B. im
Konstruktor), sondern erst in den jeweiligen Methoden
initialisiere?

Das Problem ist die rekursive Natur deines Init. Nimm das new aus dem Konstruktor komplett raus. Dann mach sowas in der Art:

a = new A();
c = new C();

a.setC©;
c.setA(a);

Bzw. wäre es ok, so wie ich es eben schon probieren wollte,
die beiden Variablen einfach static zu machen?

Das geht auch, allerdings sei dir über die Konsequenzen im Klaren. (static => 1 Objekt für alle Instanzen)

cu