9
votes

Pouvez-vous faire un objet sérialisable au moment de l'exécution?

Juste comme le titre dit, est-il un moyen de vérifier si un objet est sérialisable et, sinon, le faire ainsi au moment de l'exécution?


3 commentaires

Si l'objet n'est pas sérialisé, cela pourrait être une bonne raison: par exemple, il est peu détecté de sérialiser la connexion de base de données.


Un format de sérialisation qui n'est pas un travail de sérialisation de l'objet Java? Je pense à une solution qui utilise la réflexion et le JSON ou XML pour sérialiser l'objet. D'autres commentaires, on dirait que votre exigence est de rendre l'objet dans une chaîne et cela en accomplirait cela.


Cette question est vraiment large, en grande partie parce qu'elle ne mentionne pas toutes vos contraintes de conception. (E.G., que vous avez besoin d'un format de sérialisation à chaîne.)


7 Réponses :


1
votes

Comme d'autres ont dit ... Une réponse courte est non.

Vous pouvez absolument ajouter une interface à n'importe quel objet ancien à l'exécution à l'aide d'objets proxy comme décrit à http://download.oracle.com/javase/6/docs/technotes/guides/reflection/proxy.html . Cela inclut aussi Java.IO.Serializable. Toutefois, pour qu'un objet proxy soit utile, il doit conserver une référence interne à l'objet d'origine, qui dans votre cas ne met pas en œuvre sérialisable. La seule façon dont votre objet proxy pourrait être sérialisé est de faire référence à la référence interne à l'objet d'origine un champ transitoire et qui ne vous ferait pas beaucoup de bien.

En outre, après avoir examiné vos commentaires, il semble que Java Serialization n'est définitivement pas ce que vous voulez et que vous voulez vraiment simplement sérialiser au format de la chaîne. D'autres ont suggéré diverses solutions, mais OMI si vous voulez le moins de fausses, allez avec Xstream: HTTP : //x-stream.github.io/Tutorial.html .


4 commentaires

Les procurations sont fabriquées par interface, pas sur une classe.


@Bozho - cette partie est détaillée dans la documentation que j'ai liée à. Cela nécessiterait des changements dans son codeBase s'il n'utilisait pas déjà l'interface pour polymorphiquement (SP?) Référencez ses objets.


Son objet d'origine serait membre de l'invocalisationHandler, qui est également sérialisé, ce qui échouera.


@Bozho - Vous avez raison, ça échouerait. Il pourrait faire l'objet original un champ transitoire ... mais en termes de sérialisation qui ne fait pas beaucoup de bien: D (à l'intervalle de la récréation de fantaisie de l'état d'objet dans l'objet proxy lui-même +, ce qui rend l'objet original transitère, ce qui est bien au-delà de Fugly). En général, l'utilisation d'objets proxy est la manière dont on ajouterait de manière dynamique des interfaces à un objet, mais dans le cas de sérialisable, cela ne ferait aucun bien. Je modifierai ma réponse en tant que telle.



11
votes

Réponse courte - NO.

Réponse plus longue - Oui, en utilisant la manipulation du code octet, par exemple avec ASM. Mais vous devriez vraiment examiner si cela est nécessaire. La sérialisation est une question grave (Java efficace a tout un chapitre sur la sérialisation)

BTW, il existe des alternatives à la sérialisation binaire, qui ne nécessitent pas l'objet implémentant sérialiszble (comme indiqué par Jacob dans les commentaires):

  • xml - java.beans.xmlencoder.encode (..) est la version XML de ObjectOutPutStream
  • JSON - Frameworks comme Jacskon, Gson vous permet de sérialiser un objet avec une ligne.

0 commentaires

0
votes

whoa. Pourquoi auriez-vous besoin de cela pour être vérifié au moment de l'exécution? N'est-il pas plus facile de s'assurer qu'il se compare à la compilation? Utilisation d'un code comme celui-ci.

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

public void someMethod(SerializableInterface serializable){
}


0 commentaires

0
votes

Outre les bonnes réponses existantes, une autre question est de savoir si vous avez spécifiquement besoin de java sérialisable pour un cadre spécifique ou de pouvoir simplement être capable d'obtenir des objets sérialisement. Pour ce dernier, il y a beaucoup plus de choix que JDK par défaut; Et pour de nombreux cas d'utilisation, des alternatives sont beaucoup meilleures que JDK One.

Si vous n'avez pas spécifiquement besoin de JDK One, l'utilisation de la sérialisation JSON ou XML est souvent un bon choix.


2 commentaires

La raison pour laquelle je consulte la sérialisation est pour un projet que je souhaiterais convertir un objet à une chaîne (via un tableau d'octets) pour le stockage et la transmission où il est nécessaire d'être une chaîne en raison de facteurs externes. J'ai vu plusieurs exemples d'utiliser la sérialisation pour convertir en un flux d'octets pour capturer l'objet en tant que chaîne à la fin, mais rien sur quoi faire si l'objet n'est pas sérialisable. Je comprends que le besoin de certains objets ne soit pas sérialisé, mais dans ce cas, ce serait quelque chose de laisser à la discrétion du développeur.


OK, alors vous ne voulez certainement pas utiliser JDK Serializable. Je recommanderais d'utiliser la sérialisation JSON (comme Jackson, voir wiki.fasterxml.com/jacksoninfiveminutes ). Le résultat est plus lisible et beaucoup moins fragile. Le problème principal avec Serializable est que la versioning est très difficile, il s'agit donc d'un anti-modèle de persister les résultats (lire l'explication de Josh Bloch, par exemple). Ce n'est pas lisible, non plus (contrairement à XML ou JSON). Il n'y a rien de mal dans les choses sérialisées en soi, mais serialisable est rarement juste de bonne manière.



0
votes

Vérification au moment de l'exécution? Sûr. "Si (instance de quelque manière sérialisable) ...".

Vous voulez modifier la définition d'un objet au moment de l'exécution? Il y a très rarement une bonne raison de vouloir faire cela. Peut-être qu'il y a un moyen de le faire avec une réflexion, mais je n'ai jamais eu de raison de vouloir faire une telle chose. Qu'essayez-vous d'accomplir?


0 commentaires

1
votes

Si quelqu'un a vraiment vraiment besoin de manipuler avec Bytecode en runtime. Avec la bibliothèque Javassist peut être fait ceci:

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


0 commentaires

0
votes

Vous pouvez créer une classe Wrapper Serizlize avec un champ d'objet, puis attribuer votre objet au champ. Lorsque vous serifiez la classe wrapper, elle stockera l'objet et vous pouvez désérialiser et lancer votre objet dans le champ. XXX


0 commentaires