Java Quiz

Hier ist schon ewig nix mehr passiert und da ich gerade eine Idee für ein kleines Rätsel habe kram ich das mal aus. Ich weiß nicht ob das schonmal gepostet wurde (in ähnlicher Form?) und ich denke für die etwas erfahreneren Entwickler ist das auch nicht so schwer, aber für Anfänger ist das sicherlich erstmal kurios.

public class Test {
	public static void main(String[] args) {
		http://forum.byte-welt.net/
		for (int i = 0; i < args.length; i++) {
			System.out.println(args**);
		}
	}
}

Kompiliert dieser Code und ist er ausführbar? Wenn ja, warum? Wenn nein, warum nicht?

‘Hinweis’
[spoiler]Ich habe übrigens absichtlich die CODE-Tags statt der JAVA-Tags genommen, weil sonst durch Syntax-Highlighting wohl schon ein entscheidender Tipp gegeben worden wäre.

[SPOILER=‘Zeigs mir trotzdem!’]public class Test { public static void main(String[] args) { http://forum.byte-welt.net/ for (int i = 0; i < args.length; i++) { System.out.println(args**); } } }[/spoiler]
[/SPOILER]

Compiliert. “http:” ist in diesem Fall ein Label für die For-Schleife, dass man mit einem “break” ansprechen könnte.

[SPOILER]http:for(int i = 0; i < 10; i++){ for(int j=0; j < 10; j++){ if(i+j==10) break http; } }

Beendet die äußere Schleife, wenn i=1 und j=9 sind.

[/SPOILER]

Noch der Zusatz, dass nach dem http: dann eben ein regulärer Kommentar erscheint, weil es mit // beginnt. :slight_smile: Aber vollkommen richtig. Labels sind in Java zwar da, aber scheint nicht besonders verbreitet zu sein, deswegen mag man sich da auf den ersten Blick wundern warum das kompiliert.

Damit hier wieder mal etwas Leben herein kommt: Darf man konkrete Methoden mit abstrakten überschreiben? Ist also dieser Code legal?

public class Concrete {
    public void doIt() {
        System.out.println("I did it");
    }
}

public abstract class Abstract extends Concrete {
    public abstract void doIt();
}

public class ConcreteAgain extends Abstract {
    public void doIt() {
        System.out.println("I did it again");
    }
}

[spoiler]Ja, das sollte so legal sein. Auch die Verwendung des Klassennamens Abstract sollte kein Problem sein, weil der erste Buchstabe groß geschrieben ist.

Edit: ich meine mich zu erinnern, in einem Framework mal abstrakte hashCode und equals Klassen gesehen zu haben. Das zwingt einen beim Erweitern dann dazu, sich damit zu beschäftigen.[/spoiler]

Funktioniert so ein Interface?

public interface GenericCloneable<T extends GenericCloneable<T>> extends Cloneable {

  public T clone();

}

[spoiler]
Ich würde spontan darauf tippen, dass das funktioniert. Dass clone() in Object den Rückgabewert Object hat, sollte kein Problem sein, da man seit Java 5 speziellere (“covariante”) Typen zurückgeben darf.

Nebenbei bemerkt gehören für mich Cloneable und die clone()-Methode in die Top-Ten der Java-Hässlichkeiten.
[/spoiler]

Diskussion dazu abgetrennt nach http://forum.byte-welt.net/threads/11432-Über-Methoden-von-Object-clone()-hashCode()-und-equals()

[quote=Landei]Ich würde spontan darauf tippen, dass das funktioniert. Dass clone() in Object den Rückgabewert Object hat, sollte kein Problem sein, da man seit Java 5 speziellere (“covariante”) Typen zurückgeben darf.

Nebenbei bemerkt gehören für mich Cloneable und die clone()-Methode in die Top-Ten der Java-Hässlichkeiten.[/quote]
Ja richtig, es geht. Das ging aber auch schon vor Java 5 schon. Denn laut Vererbungsregeln war es schon immer erlaubt, in einer überschreibenden Methode spezifischere Return-Typen sowie spezifischere Exceptions zu definieren (“Keine” ist auch auch spezifischer). Die Definition des Interfaces war übrigens darin begründet, dass ich clone() so wie es von Object kommt und das Cloneable Interface auch ziemlich verunglückt finde. Nach Lektüre der entsprechenden Artikel zu clone hier: http://www.angelikalanger.com/Articles/EffectiveJava.html hab ich mir das dann überlegt. Die abgetrennte Diskussion ist ja schon etwas in eine andere Richtung gelaufen, wie ich gerade sehe.

I beg to differ:

Covariant return types have been (partially) allowed in the Java language since the release of JDK5.0, so the following example wouldn’t compile on a previous release:

Hm, Wikipedia ist ja schon ne gute Quelle. Ich muss mächtig halluzinieren, denn ich meine mich zu erinnern, dass das ein recht umfangreiches Kapitel in den Vorbereitungen zum SCP Java 2 (JDK 1.4) war (nun aber auch schon gut 10 Jahre her…). Ich schau mal, ob ich die Unterlagen noch habe…

Ich habe definitv halluziniert. Habe gerade mal Testcode geschrieben und in Eclipse das Compiler Compliance Level auf 1.3 und 1.4 gestellt. Hat nicht kompiliert.

sorry wenn das schon mal die Frage war, keine Lust 10 Seiten durchzulesen:

Object i = null;

if( i instanceof Object ){

}

Was passiert?

In keinem Fall etwas, weil kein Code dasteht, der was machen würde :wink:
[spoiler]Der if-Teil wird nicht betreten. insanceof gibt bei null false zurück. Kann man in der equals()-Methode nutzen, um gleichzeitig auf Vergleichbarkeit und null zu prüfen. Sollte man aber nur, wenn entweder equals selbst oder die Klasse final sind[/spoiler]

Set<String> unmodifiableSet = Collections.unmodifiableSet(mySet);

mySet.addAll(Arrays.asList("d", "e", "f"));

System.out.println(6 > unmodifiableSet.size() ? "ja" : "hääääää?");```

bye
TT

[spoiler]Da sollte “hääääää?” bei rauskommen, weil Collections.unmodifiableSet() nur eine Sicht auf die unterliegende Collection ist. D. h., wenn die unterliegende Collection bearbeitet wird, dann ändert sich auch die Sicht darauf.[/spoiler]
Die Zeile 6 hat übrigens am längsten gedauert sie zu verstehen. Da sieht man mal wieder, was es ausmacht, wie herum man eine Bedingung formuliert.

Waren die unmodifiable Collections nicht einfach ein Decorator, der in allen modifizierenden Methoden eine Exception wirft?
Würde mich rudolph daher anschließen :slight_smile:

Mal ein neues Quiz:

  static int x = 0;

  @Override
  public void run() {
    while(x == 0) {
      System.out.printf("X == %d%n", x);
      x = 1 - x;
    }
  }

  public static void main(String[] args) {
    new QuizT().start();
    new QuizT().start();
    new QuizT().start();
  }
}```

Was passiert? Was gibt das Programm aus?

Z.B.
0
0
0
1
0
1
0
1
usw.
Muss bicht anhalten.

Edit: Sorry, meine Antwort ist falsch, es gibt ein gleiches Ergebnis, aber welches und wieso?

[SPOILER]Ausgabe: 0 (nur ein mal)
Weil der erste Thread die Variable auf 1 setzt und damit kein anderer Thread (auch er selbst nicht) das while ausführt.[/SPOILER]

bye
TT