Warum illegal forward reference bei Exemplarinitialisierer

Status
Nicht offen für weitere Antworten.

Schandro

Top Contributor
Hi,

Zitat aus der Insel Kapitel 6.5.8:
Der Programmcode der Exemplarinitialisierer wird an den Anfang aller Konstruktoren gesetzt. Objektvariablen wurden schon initialisiert.
warum wirft der Compiler für die Klasse E einen Compilerfehler ("illegal forward reference"), für E2 aber nicht? Es ist doch egal wo das Zeug im Code steht, der Compiler schreibt zuerst alle Membervariablendeklerationen in den Code jedes Konstruktors, danach alle Exemplarinitialisierer.
Code:
class E{

	public static void main(String[] args){
		new E();
		new E2();}

	{
		System.out.println(z);
	}

	S z = new S(1);
}

class E2{

	S z2 = new S(1);

	{
		System.out.println(z2);
	}
}


class S{
	public S(int i){
		System.out.println("new S("+i+")...");
	}
}
 

0x7F800000

Top Contributor
Keine Ahnung warum aber es geht so wie du es sagst nicht.
Hier wird es auch ohne Begründung erwähnt:
Insel hat gesagt.:
Wichtig ist abschließend zu sagen, dass vor dem Zugriff auf eine Objektvariable im Exemplar-initialisierer diese auch deklariert sein muss.
 
S

SlaterB

Gast
was soll denn für System.out.println(z) rauskommen?
das Objekt S(1) nicht, denn dann ginge folgendes nicht:

Code:
public class Test {

	public static void main(String[] args) {
		new E();
	}
}

class E {

	String b = "b";

	{
		b = "c";
	}

	String a = b;

	{
		System.out.println(a);
	}
}

// Ausgabe: c
die Deklarationszeile wird also nicht einfach vor alle {}-Konstruktoren verschoben sondern ist in den zeitlichen Ablauf integriert,

man könnte sich natürlich denken, dass nur die Variablendeklation nach vorne gezogen wird und die Zuweisung nicht, also etwa
Code:
String b;
String a;
{
  b = "b";
  b = "c";
  a = b;
}
dies mag vielleicht auch genau so sein,
aber in diesem Fall macht ein Zugriff auf noch nicht bekannte Variablen keinen Sinn, denn deren Wert kann nur null oder 'nicht initialisiert' sein, wozu darauf zugreifen?
insofern kann man ruhig auf diesen Zugriff verzichten und die Vorwärtsreferenz ganz verbieten, allein schon um das Paradoxon

String a = b;
String b = a;

einfach syntaktisch zu verhindern

------------

so dachte ich zumindest ein paar Minuten,
mit folgendem Beispiel macht das aber auch nicht mehr ganz so viel Sinn:

Code:
	{
		a = "d"; // Zuweisung ist erlaubt?!
		System.out.println(a); // hier ist a wie zuvor nicht zugreifbar, 
		                       // wobei nun aber gewiss ein Inhalt ("d") vorhanden ist.. 
	}
	String a;
 
S

SlaterB

Gast
auch Inseln gehen unter ;)
wobei das vielleicht nur eine Frage der Interpretation ist
 

musiKk

Top Contributor
SlaterB hat gesagt.:
Code:
	{
		a = "d"; // Zuweisung ist erlaubt?!
		[ ... ]
	}
	String a;
Ist erlaubt, weil eine Zuweisung geschieht und nicht die Variable gelesen wird.
Solche Dinge liest man am besten in der JLS nach. War wohl doch nicht so falsch, dass einer meiner Profs immer so vehement aufs Spezifikationslesen verwiesen hat.
 
S

Spacerat

Gast
Siehts nur so aus, oder wird da im Konstruktor von "S" wirklich "new S(x)" aufgerufen? Tödliche (für's Prog natürlich) Rekursion würd' ich sagen, wenns nicht gequotet wär...
Der Fehler steckt hier wohl aber in den Zeilen 5 und 7... oder geht so ein Konstrukt?
Nach nochmaligem Überlegen:
Eclipse hat gesagt.:
Auf ein Feld kann erst dann verwiesen werden, wenn es definiert ist
in Zeile 8...
 

Schandro

Top Contributor
bei welchen code meinst du "zeile 5 und 7"?

das "new S()" im Konstruktor von S ist natürlich nur ein String...
 
S

Spacerat

Gast
Bei deinem... In Zeile 5 wird die Deklaration der Main-Methode beendet. Deswegen kommt in Zeile 7 ein Objekt-Initializer zustande, der "forward" auf eine noch nicht initialisierte Objekt-Variable zugreift. Wollte deswegen sagen, wenn man die beiden Klammern löscht gehts. Eine andere Lösung ist es, die Definition von "z" oberhalb des OIs zu platzieren.
 

Schandro

Top Contributor
jep, das ist bekannt^^
Es geht ja gar nicht darum meinen code kompilierbar zu machen, das könnt ich auch selber ;)
Es ging ja nur darum, das ich aus den Infos, die in der Insel standen, nicht wusste warum er der Compiler die Exception schmeisst
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J WARNING: An illegal reflective access operation has occurred, beim Compilieren von JasperReports, was bedeutet das ? Allgemeine Java-Themen 23
MiMa Illegal char im Dateinamen Allgemeine Java-Themen 14
C "/" in String.split()-->Illegal escapesequence Allgemeine Java-Themen 5
M Forward Deklaration in Java? Allgemeine Java-Themen 3
B Fehlermeldung von dispatcher.forward abfangen Allgemeine Java-Themen 2
C Back und Forward Allgemeine Java-Themen 7
Kirby.exe Cannot make a static reference to the non-static field rimWidth Allgemeine Java-Themen 12
R Erste Schritte Object reference funktioniert nicht. Wie mach ichs richtig? Allgemeine Java-Themen 3
M Lambda "invalid method reference no suitable method found" Allgemeine Java-Themen 2
W Threads Cannot make a static reference.. Allgemeine Java-Themen 13
M Java - Call by value <-> Call by reference Allgemeine Java-Themen 16
S Cannot make a static reference to the non-static field MySecondClass.Points Allgemeine Java-Themen 3
Kr0e Circular reference - Serialisierung Allgemeine Java-Themen 6
E wie call by reference mit Wrapper-Klassen? Allgemeine Java-Themen 2
F Pointer oder Reference? Allgemeine Java-Themen 8
G Reference-Counter Allgemeine Java-Themen 3
B Array von Vektoren by reference übergeben Allgemeine Java-Themen 5
conan2 "Cannot make a static reference to the non-static field Allgemeine Java-Themen 8
A Static reference to non-static field Allgemeine Java-Themen 10
sliwalker Call by Reference - Was stimmt denn nun ? Allgemeine Java-Themen 14
H Aus der FAQ: Call by Value <-> Call by Reference Allgemeine Java-Themen 8
O Pointer/reference on method Allgemeine Java-Themen 10

Ähnliche Java Themen

Neue Themen


Oben