Modifizieren der Standardklassen in Java

opus31337

Grünschnabel
Hallo Leute!

Ich habe einige Schwierigkeiten, die wahrscheinlich mehr mit OOP allgemein, als mit Java konkret zu tun haben.

Ich möchte die Klasse HashMap auseinander nehmen, analysieren und mit der Klasse ein bisschen rumexperimentieren. D.h. manche Methoden davon verändern, Zugriffe auf bestimmte Objekte/Methoden zählen, neue Sachen hinzufügen usw.

Natürlich kann ich das nicht direkt machen und sollte z.B. eine eigene Klasse von der HashMap ableiten. Und da fangen meine Probleme an:

das Überschreiben der Methoden funktioniert nur soweit:
Code:
	@Override
	public V put(K key, V value){
		return (V) super.put(key, value);
		
	}

d.h. ich kann nur vor und nach der Ausführung der Elternmethode etwas machen, aber nicht "mittendrin"
und wenn ich einfach die alte Implementierung komplett kopiere
Code:
    public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key);
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }
schimpft er, dass die im Code verwendete Methoden und Klassen "not visible" sind(natürlich, weil sie als private deklariert sind).


Was macht man damit?
Wie kann ich so eine Standardklasse verändern?

Wär dankbar für jede Antwort;)
 

sheel

I love Asm
Hi

Das ist das Gemeine an private.
Die Entwickler der Klasse hätten auch protected nehmen können
(hatten durch private keinen Vorteil), aber sie haben es getan,
um dir dein Vorhaben künstlich schwer zu machen :D

a) Die verwendeten private-Sachen alle selbst definieren/implementieren (andere Namen)
Also praktisch eine völlig neue Klasse, die mit dem Parent nur die Beerbung und die
Namen/Parameter/Returnwerte der public-Sachen gemeinsam hat.

b) Mit Reflections sollte ein Zugriff möglich sein.
Potenzielles Problem ist, dass sich die private-Teile von Klassen
bei verschiedenen Versionen etc. unterscheiden könnten.
 

opus31337

Grünschnabel
Hallo! Danke für die Antwort.

die Strategie a) verstehe ich nicht ganz. Die private-Sachen werden aktiv in den public-Sachen benutzt. Wenn ich sie unter einem neuen Namen implementiere, kann ich sie trotzdem nicht in die public-Sachen einpflegen. Wenn ich auch noch public-Sachen überschreiben muss, dann ist es quasi, wie die Klasse komplett neuschreiben.

Über die Reflections habe ich auch schon gelesen, allerdings noch nicht ganz durchgestiegen. Werde wohl weiter google benutzen müssen...
 

sheel

I love Asm
dann ist es quasi, wie die Klasse komplett neuschreiben.
Ja, so war es gemeint.
Nur noch deswegen erben lassen, damit man Instanzen der eigenen klasse auch irgendwo
verwenden kann, wo Instanzen des Parents erwartet werden (zB. Parameterübergabe usw.)

Reflections sind kurz gesagt eine Möglichkeit, mit dem Namen einer Variable/Methode
in einem String die Variable/Methode verwenden, aufrufen usw.
(es gibt ein paar spezielle Klassen dafür, die diese Funktionalität codemäßig anbieten)
Zu einem gewissen Grad kann private damit umgangen werden.
Problem, wie gesagt: Keiner garantiert, dass die privaten Javasachen immer
und überall gleich heißen. Wenns nach einem Java-Update umbenannt ist
geht dein Code nicht mehr.
 

opus31337

Grünschnabel
Danke für die schnelle Reaktion!

Ich habe jetzt mit etwas Copy&Paste und Umbenennen eigene Klasse "geschrieben". Der Code lässt sich problemlos kompilieren. Es fliegen allerdings Fehler bei sun.misc.Unsafe - Sachen raus... Das hab ich ja gehofft umzugehen: die Sachen zu verwenden, die ich noch nicht wirklich verstehe. Ich wollte diese Sachen wie sie sind lassen ...

Die Schwierigkeiten mit den Veränderungen von den Namen von Methoden von Version zur Version sind kein Problem für meine Zwecke. Den Code brauche ich selber nur ein mal, um meine Veränderungen am HashMap zu untersuchen und der wird nicht mehr verwendet, also such ich mal in die Richtung weiter.
 

Fasibio

Mitglied
Hallo,
du kannst auch vom Object Orientierten Weggehen und zum Aspektorientierten.
Dort sollte meies wissens sowas funktionieren.