Wie rekursiv serialisiert ein Objekt mit reflektion?
Ich navigieren möchten, um die N-te Ebene eines Objekts, und es zu serialisieren Eigenschaften im String-format.
Zum Beispiel:
class Animal {
public String name;
public int weight;
public Animal friend;
public Set<Animal> children = new HashSet<Animal>() ;
}
serialisiert werden sollen, wie diese:
{name:"Monkey",
weight:200,
friend:{name:"Monkey Friend",weight:300 ,children:{...if has children}},
children:{name:"MonkeyChild1",weight:100,children:{... recursively nested}}
}
Und Sie können wahrscheinlich feststellen, dass es ähnlich ist zum serialisieren eines Objekts in json. Ich weiß, es sind viele libs(Gson,Jackson...) kann dies tun, können Sie mir einige lehrreiche Ideen, wie diese zu schreiben, indem ich mich?
- Gibt es einen bestimmten Teil von dem, was erweist sich als schwierig?
- Wenn Sie wissen, dass es viele Bibliotheken gibt, warum nimmst du nicht einfach eine?
- Können Sie lassen Sie uns wissen, was Sie versucht haben, so weit, so haben wir einen Ausgangspunkt?
- Niessner : ich weiß nicht, wie zu kontrollieren ein Feld, das sollte rekursiv serialisiert.
- Es ist nur die einfache Rekursion: die Introspektion ein Typ (mit super-Typen etc) für Felder, Methoden (siehe JDK-javadocs für die Klasse), finden Sie die tatsächlichen Werte der Felder, die mit java.lang.reflektieren.Feld, Spülen, wiederholen. Und wenn Sie wollen bekommen Sie Lust, im Auge behalten bereits beschlossenen Objekte zu behandeln Zyklen (oder shared refs).
Du musst angemeldet sein, um einen Kommentar abzugeben.
Serialisierung ist im Grunde tief Klonen.
Sie brauchen, um zu verfolgen jedes Objekt Referenz für reoccurrencies (zum Beispiel durch Verwendung von IdentityHashMap). Was auch immer Ihre endgültige Umsetzung Methode (wenn keine externe Bibliothek) denken Sie daran, zu prüfen, Objekt reoccurrencies oder Sie können am Ende in einer infinent Schleife (wenn Objekt A hat Referenz auf Objekt B, das ebenfalls Referenz auf Objekt A oder etwas komplizierter-Schleife in einem Objektdiagramm).
Eine Möglichkeit ist die traverse durch Objekt-Graphen mit DFS-Algorithmus wie und zu bauen, die clone (serialisierte string) von dort.
Dieser pseudo-code hoffentlich erklärt, wie:
Den besuchten Satz in dem Beispiel ist, wo ich verwenden würde, Identität-set (wenn vorhanden), oder IdentityHashMap.
Wenn Sie finden, sich Felder nachdenklich (das ist der Knoten.expand() Teil) erinnern, gehen durch Oberklasse-Felder.
Reflexion sollte nicht verwendet werden, die in einer "normalen" Entwicklung der Fall. Reflexion Griffe code als Daten und Sie können Sie ignorieren alle normalen objektzugriffseinschränkungen. Ich habe diese verwendet werden, reflektierende Tiefe Kopie Zeug nur für tests:
In einem test überprüft verschiedene Arten von Objekten, die für Tiefe objektgraphen Gleichheit
In einen test, der analysiert, Objekt-graph Größe und andere Eigenschaften
Google Gson tun können diese Besondere Aufgabe in einer einzigen Zeile:
Umgekehrt geht das übrigens auch so einfach:
Ich habe nicht gesehen, ein anderes JSON-serializer noch mit besserer Unterstützung für generics, collections/maps und (geschachtelte) javabeans.
Update: Auf den Punkt, Sie brauchen nur zu lernen, über die reflection-API. Ich empfehle, um sich selbst durch die Sun tutorial zu dem Thema ersten. In einer nussschale, können Sie
Object#getClass()
und all die Methoden, die zur Verfügung gestellt vonjava.lang.Class
,java.lang.reflektieren.Methode
, etc, um zu bestimmen, das eine und andere. Google-Gson ist open source, nehmen Sie Ihrem Vorteil als gut.Einen sauberen Weg, dies zu nähern, ist die Verwendung einer Besucher Muster zu halten Sie Ihre Codierung Implementierung getrennt von Ihrem business-objects -. Einige Leute behaupten, dass Sie einfach zu implementieren die
Externalizable
- Schnittstelle zusammen mitreadExternal
/writeExternal
aber das hat die Probleme, dass:Beispiel
Normalerweise würde man dann definieren Sie eine stateful
Encoder
Umsetzung, das wäre "push" jedes Objekt zu einemOutputStream
wenn seinevisitXXX
- Methode aufgerufen wird; z.B.