[SPOILER]
In der Main wird eine Instanz erzeugt
bevor der Konstruktor ausgefuehrt wird werden die Class-members initialisiert
das ganze wird von oben nach unten durchgemacht.
daher ist a null
b bekommt den Wert b
nun wird ref erzeugt und der Konstruktor augerufen
daher kann zu diesem zeitpunk eigentlich nur b einen Wert haben und alles andere muss null sein.
vl dass c auch schon den Wert c bekommen hat, da es final ist, bin mir aber nicht sicher
[/SPOILER]
Würde mal spontan auf:
a: null
b: b
c: null
d: null
ref: null
tippen. a, b, d und ref sind relativ klar. c könnte eventuell noch “c” sein wenn das inlined wird.
b schon initialisiert ist (weil es vor dem „new SomeClass(this)“ steht) aber d noch nicht
c schon initlialisiert ist (weil es final und der Wert zur Compilezeit bekannt ist), aber d noch nicht
Dass die „in Lesereihenfolge“ initialisiert werden, hätte man raten können. Dass das „final“ dafür sorgt, dass diese Reihenfolge aufgebrochen wird, ist aber ein ziemlich fieses Detail…
Ohje… jetzt hab’ ich durch die letzte Antwort die Anforderungen für so eine “Erklärung” in kaum handabbare Höhen geschraubt… :eek: Aber immerhin wurde mir dadurch eine Ungenauigkeit bewußt (ist oben schon entsprechend ergänzt).
Es schwierig, hier “mit dem Finger auf die entsprechende Stelle zu zeigen”. In der JLS, 13.1. The Form of a Binary, ist erwähnt: 3. References to fields that are constant variables (§4.12.4) are resolved at compile time to the constant value that is denoted.
Das, in Kombination mit 12.5. Creation of New Class Instances, Punkt 4, **Execute the instance initializers and instance variable initializers for this class, assigning the values of instance variable initializers to the corresponding instance variables, in the left-to-right order in which they appear textually in the source code for the class. ** (was noch vor dem Ausführen des Konstruktors passiert), ist wohl die Erklärung für das Verhalten, das in diesem Beispiel nochmal ausführlicher demonstriert ist:
class InitializationTestUser
{
public InitializationTestUser(InitializationTest initializationTest)
{
System.out.println("State: ");
System.out.println(" am: "+initializationTest.am);
System.out.println(" a: "+initializationTest.a);
System.out.println(" ma: "+initializationTest.ma);
System.out.println(" bm: "+initializationTest.bm);
System.out.println(" b: "+initializationTest.b);
System.out.println(" mb: "+initializationTest.mb);
System.out.println(" cm: "+initializationTest.cm);
System.out.println(" c: "+initializationTest.c);
System.out.println(" mc: "+initializationTest.mc);
System.out.println(" dm: "+initializationTest.dm);
System.out.println(" d: "+initializationTest.d);
System.out.println(" md: "+initializationTest.md);
}
}
public class InitializationTest
{
public static void main(String[] args)
{
InitializationTest t = new InitializationTest();
}
String am = ma();
String a = "a";
String ma = ma();
final String bm = mb();
final String b = "b";
final String mb = mb();
final InitializationTestUser ref = new InitializationTestUser(this);
String cm = mc();
String c = "c";
String mc = mc();
final String dm = md();
final String d = "d";
final String md = md();
private String ma()
{
return a;
}
private String mb()
{
return b;
}
private String mc()
{
return c;
}
private String md()
{
return d;
}
}```
State:
am: null
a: a
ma: a
bm: b
b: b
mb: b
cm: null
c: null
mc: null
dm: null
d: d
md: null
[ul]
[li] `am` ist null, weil die Initialisierung vor der von `a` erfolgt[/li][li] `a` ist nicht null, weil die Ausgabe nach der Initialisierung erfolgt[/li][li] `ma` ist nicht null, weil die Initialisierung nach der von `a` erfolgt[/li][li] `bm` ist nicht null, weil die Initialisierung von `b` schon zur Compilezeit stattfindet[/li][li] `b` ist nicht null, weil die Initialisierung schon zur Compilezeit stattfindet[/li][li] `mb` ist nicht null - klar ;)[/li][li] `cm` ist null, weil die Ausgabe vor der Initialisierung erfolgt[/li][li] `c` ist null, weil die Ausgabe vor der Initialisierung erfolgt[/li][li] `mc` ist null, weil die Ausgabe vor der Initialisierung erfolgt[/li][/ul]
Eigentlich müßte man wohl noch genauer differenzieren zwischen den Fields selbst und ihren Referenzierungen, aber zumindest scheint es so plausibel...
@cmrudolph hat Recht. Das weggelassene „static“ beim „nicht“ (oder das vorhandene bei den anderen beiden) ist vielleicht ein bißchen gemein, aber … das funktioniert
zuerst wird im try 0 zurückgegeben und anschließend um 1 erhöht. und ich glaub eher , dass jetzt erst der finally block dran kommt und daher den Wert 1 noch einmal erhöht und den vorherigen Rückgabe wert mit 2 “überschreibt”
Jo stimmt, … es ging darum dass er das “i++” wirklich ausführt und schon alles vorbereitet, um das zurückzugeben, aber das finally wirklich im letzten Moment reingrätscht und alles ändert…
Noch ein kleines quiz, inspiriert von einer anderen Frage:
public class CompareTest
{
public static void main(String args[])
{
float a = 0;
float b = 0;
a += 0.7;
b += 0.5;
if (a < 0.7)
{
if (b < 0.5)
System.out.println("Both smaller");
else
System.out.println("One smaller");
}
else
System.out.println("None smaller");
}
}
Interessant: Scheibt man die Initialisierung gleich in die Variablen (float a = 0.7f; float b = 0.5f), muss man den Code noch nicht mal laufen lassen. Da meckter Ecplise so schon über “Dead Code”.
Eigentlich kann ich mir kaum vorstellen, dass was anderes außer “None smaller” ausgegeben werden sollte. Denn trotz des Problems, dass Gleitkommazahlen sich nicht exakt abbilden lassen, wird doch in beiden Fällen derselbe “Rundungsfehler” gemacht, sodass < x auf jeden Fall falsch sein müsste.
Aber: so wie das Beispiel gestellt ist, kann es natürlich sein, dass durch die Addition was anderes in a steht als das, was bei dem Vergleich mit einer Konstanten verwendet wird.
Vom logischen her: None smaller
Vom überprüfen her: One smaller
Meine begründung schlicht und einfach die Darstellung von floatzahlen. Da dort ja immer ungenauigkeiten auftreten können nund 0,5 einfacher bzw genauer darstellbar ist als 0,7. Dadurch wird 0,7 eben nicht genau 0,7 sein. (Erklärung vllt falsch aber denke der Gedanke stimmt^^)
Btw: Ich hatte die hoffnung das strictfp was bringt aber ändert auch nichts.