Java Quiz

Verblüffend. Bei zwei gegen eins könnte man auf die kleingeschriebenen tippen, oder auf die beiden Java-Varianten gegen den anderen. Ich kann aber nur wild raten.

2x false und 1x true, dann kann es nur das 3. sein, denn nur der Wert des 3. kann aus einem vorherigen gebildet werden.

Schönes Beispiel… denn es zeigt, wann == außerdem klappt, obwohl es “nicht” klappen sollte.

Viele nehmen statt equals ja das einfacherere ==; dass es auch funktioniert, wo ein Funktionieren nicht unüberraschend ist, deutet dann direkt auf einen Fehler hin.

Also bei mir
Linux, openjdk version „1.8.0_161“
OpenJDK Runtime Environment (build 1.8.0_161-b14)
OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)

kommt dreimal true

Wenn ich grad nichts völlig durcheinander bringe, werden String-Literale erst beim ersten „wirklichen“ benutzen oder eben mit intern in den String-Pool gelegt.
In dem obigen Code ist jeweils die mit new Erzeugte Instanz die, die bei intern im Pool landet, weil sie vor dem Literal benutzt wird. Da der Literal immer der String aus dem Pool ist, ist das dann die gleiche Instanz, wie die mit new Erzeugte.

Das „java“ (und „true“/„false“) dabei Ausnahmen sind, liegt vermutlich daran, dass die in der Oracle-JVM aus irgendeinem Grund schon im String-Pool liegen.

Annähernd richtig (und verständlich)? :sweat_smile:

1 „Gefällt mir“

@AmunRa Ja, bei

char[] ct = { 't', 'r', 'u', 'e' };
String st = new String(ct);
String sti = st.intern();
String sts = "true";
System.out.println(st == sts);// false

könnte/sollte dann aber auch false rauskommen.

Die Antwort von @mrBrown ist „almost certainly correct“ :wink: wie ich auch unter

geschrieben hatte. Der String "java" wird wohl (auf Windows/Oracle etc) schon von der JVM selbst in den Pool gepackt, und man bekommt damit schon eine gepoolte Instanz. In meiner Antwort hatte ich da noch etwas Evidenz untergebracht, mit System#identityHashCode.

Was macht der Compiler mit

switch(string) {
case "m":
// [insert code here]
break;
}

Sprich wie sieht der Code aus wenn man ihn wieder decompilieren würde.

Schauen wir uns das Beispiel an:

public class SWTest {
	public static void main(String[] args) {
		switch(args[0]) {
			case "m":
			System.out.println("the string was m");
			break;
		}
	}
}

Das javap -c SWTest:

Compiled from "SWTest.java"
public class SWTest {
  public SWTest();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: aload_0
       1: iconst_0
       2: aaload
       3: astore_1
       4: iconst_m1
       5: istore_2
       6: aload_1
       7: invokevirtual #2                  // Method java/lang/String.hashCode:()I
      10: lookupswitch  { // 1

                   109: 28
               default: 39
          }
      28: aload_1
      29: ldc           #3                  // String m
      31: invokevirtual #4                  // Method java/lang/String.equals:(Ljava/lang/Object;)Z
      34: ifeq          39
      37: iconst_0
      38: istore_2
      39: iload_2
      40: lookupswitch  { // 1

                     0: 60
               default: 68
          }
      60: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;
      63: ldc           #6                  // String the string was m
      65: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      68: return
}

Das Decompilierte:

import java.io.PrintStream;

public class SWTest
{
  public static void main(String[] paramArrayOfString)
  {
    switch (paramArrayOfString[0])
    {
    case "m": 
      System.out.println("the string was m");
    }
  }
}

Fazit:

Da da sowohl String.hashCode:() wie auch String.equals:( vorkommt, würd’ ich sagen, wird erst auf den Hash geschaut und dann auf den equals…
Außerdem werden daraus zwei Switches!?
Sind Hashes nicht gleich: Sind equals gleich: System.out
Sind Hashes gleich: System.out
Sind Hashes nicht gleich: Sind equals nicht gleich: return

Was ist eigentlich nochmal die Frage gewesen?

String s;
switch ((s = args[0]).hashCode()) { 
            default: break; 
            case -123123: if (s.equals("m")) { 
                System.out.println("the string was m"); } 
                break; 
}

Es war ein Quiz und kein ich schau die Antwort nach :stuck_out_tongue:
Aber ja, er vergleicht den hash Code im Switch statement und im case vergleicht er dann nochmal per equals die Strings direkt.
Irgendwie hatte ich mir das eleganter vorgestellt.

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: