Java Quiz

Doppelquiz!

Bitte nicht die Antwort nachschauen,
was wird ausgegeben werden?

for (int i = 0; i < 1; System.out.println(i++ + i++), System.out.println(i++ + " " + i++))
    ;
for (int i = 0; i < 1; System.out.println(++i + ++i), System.out.println(++i + " " + ++i))
    ;

(Und ja es muss ja etwas gemeines dabei sein. :wink: )

Vergesst bitte nicht, Details zu verstecken.

Das weiß jeder fortgeschrittene Java Entwickler, aber ich mag die Frage trotzdem um eine kleine aber interessante Wissenslücke zu stopfen, weil das gerne mal übersehen oder vergessen wird im immer wiederkehrenden Kontext der Standard for-Schleife…

@TMII Hast du auch eine Antwort? Du kannst sie ja spoilern.

Kompliziert das jetzt am Handy zu lösen aber man kann eine typische for-Schleife
for(int i = 0; i < n; i++)
genauso gut so schreiben
for(int i = 0; i++ < n; )

Nun macht doch jemand mal ein paar Vorschläge, was ausgegeben werden könnte!

1 2 3 4 ist es nicht, so viel mal vorab.

1 2 3
3 3 4
wenn es dich glücklich macht :stuck_out_tongue:

Weiter geht es. :slight_smile:

i läuft von 0 bis 63:

Was wird berechnet? Und was sollte man sinnvollerweise für das ? als Bezeichnung wählen?

String ? = (i + (i % 16) < 8 ? 0 : 1) % 2 == 0 ? "1" : "0";

Sorry ich habe Klammern vergessen:

String ? = (i + ((i % 16) < 8 ? 0 : 1)) % 2 == 0 ? "1" : "0";

Welcher String da rauskommt ist ja nicht so schwer zu ermitteln (auch ohne IDE).

Aber wofür das dann steht? Keine Ahnung. Hast du einen Tipp?

Vorerst sicherlich nicht. Denn der Hauptaccount des Users ist noch bis (mind.) 1. März gesperrt.

Danke für die info. Dass es der Zweitaccount eines bekannten Users ist hatte ich mir schon fast gedacht :wink: Inzwischen hat er mir auf indirektem weg einen Tipp gegeben.

Ich hatte tatsächlich zuerst an ein Schachbrett gedacht. Fand das wegen der fehlenden Zeilenumbrüche zu schräg gedacht.

Nach diesem Tipp ist das Rätsel nicht mehr so interessant. Ich hatte gehofft, da steckt eine spannende Idee dahinter. Insofern braucht niemand mehr eine Brieftaube losschicken :slight_smile:

Hatte ich vielleicht schonmal gepostet, aber …

class SomeClass
{
    public SomeClass(DangerousSelfReference dangerousSelfReference)
    {
        System.out.println("State: ");
        System.out.println("   a: "+dangerousSelfReference.getA());
        System.out.println("   b: "+dangerousSelfReference.getB());
        System.out.println("   c: "+dangerousSelfReference.getC());
        System.out.println("   d: "+dangerousSelfReference.getD());
        System.out.println(" ref: "+dangerousSelfReference.getRef());
    }
}

public class DangerousSelfReference
{
    public static void main(String[] args)
    {
        DangerousSelfReference d = new DangerousSelfReference();
    }

    private String a;
    private String b = "b";
    private final SomeClass ref = new SomeClass(this);
    private final String c = "c";
    private String d = "d";

    DangerousSelfReference()
    {
        a = "a";
    }

    String getA()
    {
        return a;
    }
    String getB()
    {
        return b;
    }
    String getC()
    {
        return c;
    }
    String getD()
    {
        return d;
    }
    SomeClass getRef()
    {
        return ref;
    }
}

Was ist die Ausgabe?

Zusammenfassung

Ich Tipp Mal auf ref: null. Der Konstruktor wird ausgeführt bevor die Referenz hinterlegt wird.

Die Frage bezog sich auf den ganzen State:

State: 
   a: ???
   b: ???
   c: ???
   d: ???
 ref: ???

Aber die Teilantwort war schon richtig.

Meine Idee

a=null // da der Konstruktor von DangerousSelfReference erst nachdem alle member variablen initialisiert worden sind ausgeführt wird.
b=“b”
c=“c” //hier rate ich nur dass der compiler dies schon auflöst, da es final ist.
d=null //ist noch null da der Konstruktor von SomeClass zuerst ausgeführt wird, da die members einfach von oben nach unten durcggegangen werden.
ref=null //Konstruktor wird vor der Zuweisung ausgeführt.

AFAIK hat sich das Verhalten zwischen der Oracle 8 und Oracle 9 JVM in diesem Fall geändert.
Ich meine zumindest das ein ähnlicher Fall erst mit J9 zu einem Absturz geführt hatte, weil die Reihenfolge der Initialisierung sich änderte.

@AmunRa Richtig.

Details

Das Beispiel hatte ich hier als Antwort gepostet:

https://stackoverflow.com/a/23264885/3182664

Ich finde, gerade die Tatsachen dass

  • b initialisiert ist und d nicht (weil er “von oben nach unten” durchgeht)
  • c initialisiert ist und d nicht (weil c dort final ist)

sind Sachen, bei denen man zumindest kurz zögern und (dann vielleicht richtig raten, aber) nur schwer “mit Sicherheit” die richtige Antwort geben könnte.

hast du im Bytecode einmal kontrolliert,ob der compiler c überhaupt anlegt und nicht einfach in der getc Methode inlined? Macht der compiler überhaupt solche Optimierungen?

Kontrolliert nicht, aber da man sich mit Reflection die Fields abholen kann (und mit JNI auch final fields ändern kann) ist er da im Handlungsspielraum etwas eingeschränkt…

Mal wieder ein kleines, klassisches Quiz-Schmankerl:

List<Object> list = new ArrayList<Object>();
list.add("Do you know what");
list.add(list);
list.add("contains?");
System.out.println(list);

Was passiert? Wird etwas ausgegeben? Wenn ja, was?

1 „Gefällt mir“