2016-08-05 35 views
2

Ich verstehe dies eine schreckliche Hack ist, aber ich bin erforderlich, um eine externe Bibliothek zu bearbeiten, um unser Projektes der Bedürfnisse anzupassen. Das Projekt, das ich verändere, speichert eine Zuordnung von Klassen zu Instanzen dieser Klassen. Die ursprüngliche Absicht des Projekts ist es, doppelte Klassen zu vermeiden, aber ich benötige sie. Meine Lösung besteht darin, ein UniqueClass-Feld auf jedes relevante Objekt anzuwenden, und dann hat jedes Objekt auch einen Verweis auf die Klasse, zu der ich eine Instanz erstellen muss. Auf diese Weise spielt die UniqueClass überhaupt keine Rolle, nur dass sie einzigartig ist.Erstellen eine einzigartige Klasse zur Laufzeit für die Verwendung als Schlüssel in einem HashMap

Nun, ich brauche einen Weg, um eine einzigartige Klasse zur Laufzeit erstellen in dieser Karte zu speichern. Hier sind die Optionen, die ich sehe:

  1. Generieren und kompilieren Sie die tatsächlichen .java-Dateien zur Laufzeit. Ich habe dies tatsächlich implementiert und es funktioniert, aber es ist etwas langsam und erfordert JDK (funktioniert nicht mit JRE, da es Zugriff auf bestimmte Bibliotheken benötigt). Ich möchte keine JDK-Konfiguration benötigen, da Nicht-Entwickler diese Funktionalität wahrscheinlich verwenden werden.

  2. eine einzigartige anonyme Klasse generieren. Das funktioniert, aber nur mit dem ersten Duplikat. Alle zusätzlichen Duplikate werden genauso behandelt wie die ursprüngliche anonyme Klasse (ClassBuilder $ 1). Ich habe here gelesen, es ist möglich, ClassBuilder $ 2 usw. zu haben, aber ich weiß nicht, wie man das macht.

    Object object = new Object(){}; 
    return object.getClass(); 
    
  3. Verwenden Sie eine Proxy-Klasse. Ich verstehe diese nicht wirklich, aber es hatte die gleichen Ergebnisse wie die anonyme Klasse oben, da die Javadocs angeben, dass, wenn eine Proxy-Klasse bereits existiert, diese nur zurückgegeben wird.

    Class proxyClass = Proxy.getProxyClass(inter.class.getClassLoader(), new Class[] { inter.class }); 
    return proxyClass; 
    
  4. (wirklich die schrecklichste Art und Weise) ein Paket von Klassen erstellen, die als jede iterativ durch sind, wird als UniqueClass verwendet. Hässlicher Code, viele unnötige Klassen und letztendlich eine Begrenzung der Anzahl der möglichen Duplikate.

Gibt es eine elegante Lösung für dieses Problem?

+0

Ich würde vorschlagen, suche die Bibliothek, wenn möglich, anstatt „Trick“ es außer Kraft zu setzen/verlängern. Wenn Sie es austricksen müssen, können Sie CGLib https://github.com/cglib/cglib/wiki/Tutorial verwenden. Beachten Sie, dass Klassen in Java 7 und niedriger in Permgen gespeichert sind. Wenn Sie diese in einer offenen Methode erstellen, kann dies zu Permgen-Fehlern führen, die Ihre App normalerweise zum Stillstand bringen. – Taylor

+0

Wenn Sie _ "eine externe Bibliothek bearbeiten" sagen _ meinen Sie, dass Sie Zugriff auf den Quellcode der Bibliothek haben und diesen ändern können? Oder müssen Sie nur mit den .class-Dateien arbeiten? –

+0

Verwendet die Map in der Bibliothek direkt Objekte der Klasse als Schlüssel? Wickelt es sie in etwas anderes? Es gibt eine Menge wichtiger Zusammenhänge, die Sie mit uns teilen müssen, oder Sie riskieren, dass dies zu einem [XY-Problem] wird (http://xyproduct.info) –

Antwort

0

Ich Modifizieren der Quellcode selbst.

In diesem Fall erstellen Sie ein Wrapper-Objekt, das als Schlüssel in Map verwendet werden soll. Sie können außer Kraft setzen equals() und hashCode() als notwendig, um Ihre Ziele zu erreichen. Im Wesentlichen fügen Sie Ihrer vorhandenen Multi-Map von Klassen und Instanzen eine weitere Indirektionsebene hinzu.

+0

Das habe ich auch versucht, aber es hat nicht funktioniert, weil die Bibliothek mehr indirekte Abhängigkeiten von dieser Karte hat, die genau Klassen enthält. Das heißt, es prüft indirekt, ob die Klasse in der Karte existiert, basierend auf einer separat erzeugten Instanzklasse. Ich kann hashCode() überschreiben, um die Klasse zurückzugeben und dieses Problem zu beheben, aber dann bin ich wieder da, wo ich angefangen habe. –

+0

Möglicherweise müssen Sie auch die 'Map'-Implementierung von der Unterklasse ableiten, um die Suchvorgänge korrekt durchzuführen. –