2010-09-07 10 views
7

Genau wie der Titel sagt, gibt es eine Möglichkeit zu überprüfen, ob ein Objekt serialisierbar ist, und wenn nicht, machen Sie es zur Laufzeit?Können Sie ein Objekt zur Laufzeit serialisierbar machen?

+0

Wenn das Objekt nicht serialisierbar ist, könnte es für einen guten Grund: Mit Bibliothek Javassist kann dies geschieht zum Beispiel, macht es wenig Sinn Datenbankverbindung zu serialisieren. –

+1

Würde ein Serialisierungsformat, das keine Java-Objekt-Serialisierung ist, funktionieren? Ich denke an eine Lösung, die Reflektion und JSON oder XML verwendet, um das Objekt zu serialisieren. Aus anderen Kommentaren klingt es wie Ihre Anforderung ist, das Objekt in einen String zu machen, und das würde dies erreichen. –

+0

Diese Frage ist sehr weit gefasst, vor allem weil sie nicht alle Ihre Design-Einschränkungen erwähnt. (Z. B. dass Sie ein Zeichenfolgenserialisierungsformat benötigen.) – jpaugh

Antwort

11

Kurze Antwort - Nr.

Längere Antwort - ja, mit Byte-Code-Manipulation, zum Beispiel mit Asm. Aber du solltest wirklich darüber nachdenken, ob das nötig ist. Serialisierung ist eine ernste Angelegenheit (Effective Java hat ein ganzes Kapitel über die Serialisierung)

BTW, gibt es Alternativen zu binärer Serialisierung, die Serializble nicht das Objekt erfordert Implementierung (wie von Jacob in den Kommentaren darauf):

  • XML - java.beans.XMLEncoder.encode(..) ist die XML-Version von ObjectOutputStream
  • JSON - Frameworks wie Jacson, Gson können Sie ein Objekt mit einer Zeile serialisieren.
+0

+1 für die Aufnahme entsprechender Warnungen. – DJClayworth

1

Wie andere gesagt haben ... kurze Antwort ist Nein.

Sie können absolut eine Schnittstelle zu jedem alten Objekt zur Laufzeit Objekte unter Verwendung von Proxy hinzufügen, wie bei http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html beschrieben. Dies beinhaltet auch java.io.Serializable. Damit ein Proxy-Objekt jedoch nützlich ist, muss es einen internen Verweis auf das ursprüngliche Objekt beibehalten, das in Ihrem Fall kein Serializable implementiert. Die einzige Möglichkeit, Ihr Proxy-Objekt serialisieren zu können, besteht darin, die interne Referenz auf das ursprüngliche Objekt zu einem transienten Feld zu machen, und das würde Ihnen nicht viel Gutes bringen.

Weiter, nach Prüfung Ihrer Kommentare, es sieht aus wie Java-Serialisierung ist definitiv nicht das, was Sie wollen, und Sie wollen wirklich nur in ein String-Format zu serialisieren. Andere haben verschiedene Lösungen vorgeschlagen, aber IMO, wenn Sie die geringste Menge an Aufwand wollen, gehen Sie mit XStream: http://x-stream.github.io/tutorial.html.

+0

Proxies werden über die Schnittstelle erstellt, nicht über eine Klasse. – Bozho

+0

@Bozho - dieser Teil ist in der Dokumentation beschrieben, die ich verlinkt habe. Es würde einige Änderungen in seiner Codebasis erfordern, wenn er Interface nicht bereits verwendet, um polymorph (sp?) Auf seine Objekte zu verweisen. – whaley

+1

Sein ursprüngliches Objekt wäre ein Mitglied des InvocationHandler, der ebenfalls serialisiert wird, was fehlschlagen wird. – Bozho

0

Whoa. Warum sollte es zur Laufzeit überprüft werden? Ist es nicht einfacher, es zur Kompilierzeit zu sichern? Einen Code einfach so verwenden.

public void someMethod(Serializable serializable){ 
} 

Oder Sie können es komplexer machen.

public interface SerializableInterface implements Serializable{ 
// bla-bla 
} 

public void someMethod(SerializableInterface serializable){ 
} 
0

Neben bestehenden guten Antworten, ist eine andere Frage, ob Sie speziell für spezifische Rahmen Java Serializable benötigen oder brauchen nur in der Lage Objekte Serializer sein. Für Letzteres gibt es viele viel mehr Auswahlmöglichkeiten als JDK Standard eins; und für viele Anwendungsfälle sind Alternativen viel besser als JDK.

Wenn Sie JDK nicht unbedingt benötigen, ist die Verwendung von JSON oder XML-basierter Serialisierung oft eine gute Wahl.

+0

Der Grund, warum ich die Serialisierung betrachte, ist für ein Projekt Ich möchte ein Objekt in einen String (durch ein Byte-Array) für die Speicherung und Übertragung konvertieren, wo es aufgrund externer Faktoren ein String sein muss. Ich habe einige Beispiele gesehen, wie man die Serialisierung in einen Byte-Stream umwandeln kann, um das Objekt am Ende als String zu erfassen, aber nichts darüber, was zu tun ist, wenn das Objekt nicht serialisierbar ist. Ich verstehe, dass bestimmte Objekte nicht serialisiert werden müssen, aber in diesem Fall liegt es im Ermessen des Entwicklers. –

+0

Ok, dann willst du definitiv JDK Serializable nicht benutzen. Ich würde empfehlen, JSON-Serialisierung (wie Jackson, siehe http://wiki.fasterxml.com/JacksonInFiveMinutes) zu verwenden. Das Ergebnis ist lesbarer und weniger fragil. Das Hauptproblem mit Serializable ist, dass die Versionierung sehr schwierig ist, also ist es ein Anti-Pattern, um Ergebnisse zu erhalten (lesen Sie zum Beispiel Josh Blochs Erklärung). Es ist auch nicht lesbar (anders als xml oder json). Es ist nichts falsch daran, Dinge per se zu serialisieren, aber Serializable ist selten der richtige Weg. – StaxMan

0

Überprüfung zur Laufzeit? Sicher. "if (someObject instanceof Serializable) ...".

Sie möchten die Definition eines Objekts zur Laufzeit ändern? Es gibt sehr selten einen guten Grund, dies zu wollen. Vielleicht gibt es eine Möglichkeit, dies mit Nachdenken zu tun, aber ich hatte nie einen Grund, so etwas zu wollen. Was versuchst du zu erreichen?

0

Wenn jemand wirklich wirklich wirklich mit Bytecode in Runtime manipulieren muss.

ClassPool pool = ClassPool.getDefault(); 
CtClass cc = pool.get("mypackage.MyClass"); 
cc.addInterface(pool.get("java.io.Serializable")) 
Verwandte Themen