Java Rätsel

Was ist die Ausgabe des Beispielcodes unter:
http://www.tutorials.de/forum/1630760-post5.html
und warum?

Einträge in einem Set müssen immutable sein, sonst können Duplikate entstehen. Offensichtlich ist das bei der konkreten Map.Entry Klasse nicht der Fall. Die IdentityHashMap scheint immer das selbe interne Objekt zu recyceln. So zeigen alle Referenzen auf das selbe Objekt. Würde man die HashMap in einer Schleife sequenziell befüllen, müsste man das sehen können. Warum die Add-Methode die Duplikate nicht erkennt ist mir jedoch noch ein Rätsel. Ich bleibe dran.

Ich weiss, dass die Erklärung noch etwas wage ist. Bin ich auf dem richtigen Weg?
 
Ich glaube ich habe habe es. Die Add-Methode ermittelt den HashCode des zu speichernden Objektes. Dieser wird als Key für die Referenz benutzt. Der nächste Aufruf von Add ermittelt einen anderen Hashcode aus den Objektdaten, also wird die Referenz mit dem anderen Hashcode in das Set eingetragen. Beide Refenzen zeigen nun aber auf das one and only Objekt. Das ist es oder?
 
@Kai008
"aber soweit ich weiß kommt bei einer static jedes mal der selbe Returnwert oder so, was auch immer das für einen Sinn haben mag."
Wo hast du dass denn aufgeschnappt? static an einer Methode bedeutet nur dass es nicht abhängig von einer Instanz der Klasse ist sondern direkt mit Klasse.methode aufgerufen werden kann. Kann man für Methoden nutzen die auf keinen Zustand angewiesen sind.
Ach sooooooo, danke. Jetzt verstehe ich auch warum die Main static ist: Weil keine Instanz eines Überobjekt's intialisiert ist was sie aufrufen könnte kann sie nur aufgerufen werden wenn sie unabhängig eines anderen Objekts ist.
Die Frage kommt aus der Zeit als ich mich mit OOP auseinandergesetzt habe. Damals hat die Main noch alles erledigt (anderst als jetzt wo nur ein "new" drinnensteht), und ich habe der Klasse "Soldat" ein Static verpasst weil es in der Paint dadurch verlangt wurde, und ein Bekannter hat "wenn die variablen static sind, dann sind se für alle soldaten gleich
" als ich ihm nach einen Fehler gefragt habe geschrieben.
Deshalb bin ich davon ausgegangen dass ein return() auch immer den selben Wert zurückliefert.
 
Ich habe eine Abstrakte Klasse, von dieser erben 2 Kindklassen. Beide haben identische codierte Methoden. Könnte diese nicht besser in der in der abstrakten Klasse implementiert werden. kann es Gründe für folgende Lösung geben?

Java:
package de.tutorials;

public abstract class AbstractParent {
	
	public abstract void doSomeThingWithWorker(Worker worker);

}

Java:
package de.tutorials;

public class ConcreteChild1 extends AbstractParent {

	@Override
	public void doSomeThingWithWorker(Worker worker) {
		
		worker.work(this);
	}

}

Java:
package de.tutorials;

public class ConcreteChild2 extends AbstractParent {

	@Override
	public void doSomeThingWithWorker(Worker worker) {
		
		worker.work(this);
	}

}

Sieht doch ziemlich redundant aus. Oder ist es das nicht?
 
Da "this" zur Funktion "work" mitgeliefert wird, kann die Klasse "Worker" auf beide erbenden Klassen individuell "eingehen", falls du das gemeint hast. Denke zwar eher nicht weil das wohl zu einfach ging, aber will mal mein Glück versuchen. =)
 
@kai008

Du hast im Prinzip recht. Aber warum kann ich die Methode nicht in der abstrakten Klasse implementieren? Diese ist selbst ja nicht instanziierbar. Also würde der this-Zeiger der abstrakten Klasse ja sowieso immer auf eine der Childinstanz zeigen.

Schlimmstenfalls passiert dies :

Java:
package de.tutorials;

public class Main {
	
	public static void main(String[] args) {
		
		AbstractParent referenz = new ConcreteChild1();
		
		referenz.doSomeThingWithWorker(new Worker());
	}

}


Könnte ich da nicht einfacher und besser auf die "doSomeThingWithWorker"-Methode verzichten und gleich folgenden Aufruf ausführen?

Java:
package de.tutorials;

public class Main {
	
	public static void main(String[] args) {
		
		AbstractParent referenz = new ConcreteChild1();
		
		new Worker().work(referenz);
	}

}
 
Zuletzt bearbeitet:
Hallo,

was ist die Ausgabe hiervon und warum:
Java:
/**
 * 
 */
package de.tutorials;
/**
 * @author Tom
 */
public class Main {
    public static void main(String[] args) {
        System.out.println("null".equals(String.valueOf((Object)null)));
        System.out.println("null".equals(String.valueOf(null)));
    }
}

Gruß Tom
 
Hallo,

die Ausgabe:
Java:
true
Exception in thread "main" java.lang.NullPointerException
    at java.lang.String.<init>(Unknown Source)
    at java.lang.String.valueOf(Unknown Source)
    at de.tutorials.NullStringEqualsNull.main(NullStringEqualsNull.java:17)

Erklärung:
Beim ersten Aufruf wird die Überladung mit String(Object value) Signatur der valueOf Methode aufgerufen.
Java:
public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
    }

Beim zweiten Aufruf wird jedoch auf die String (char[] data) Variante gegangen. Da hier davon ausgegegan wird, dass das char[] nicht null ist, kommt hier im weiteren Verlauf eine NullPointerException zu stande.
Java:
    public static String valueOf(char data[]) {
    return new String(data);
    }

Tja, nur warum wird hier beim zweiten Aufruf die String (char[] data)? Weil diese nach Java Language Specification die am besten passende Variante für die Eingabe ist. Warum? - Das wird durch eine ganze Menge von ziemlich komplizierten Regeln in der JLS beschrieben, wie ihr hier nachlesen könnt:

15.12 Method Invocation Expressions
http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#292575

Gruß Tom
 
Zurück