Java Sérialisation Personnalisée
J'ai un objet qui contient un peu de unserializable champs que je veux pour sérialiser. Ils sont d'un autre API que je ne peux pas changer, afin de faire Sérialisables n'est pas une option. Le principal problème est l'Emplacement de la classe. Il contient quatre choses qui peuvent être sérialisé que j'avais besoin, tous les services de renseignements. Comment puis-je utiliser la lecture/writeObject pour créer une sérialisation personnalisée méthode qui peut faire quelque chose comme ceci:
//writeObject:
List<Integer> loc = new ArrayList<Integer>();
loc.add(location.x);
loc.add(location.y);
loc.add(location.z);
loc.add(location.uid);
//... serialization code
//readObject:
List<Integer> loc = deserialize(); //Replace with real deserialization
location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));
//... more code
Comment puis-je faire cela?
- veuillez noter qu'il est préférable d'accepter la meilleure réponse et non pas le premier correcte. vous l'avez dit vous-même que la réponse de peter lawrey peut-être mieux. pour le bien de tous les gens de venir ici, dans l'avenir, la recherche de la meilleure réponse: veuillez envisager d'accepter une réponse différente!
Vous devez vous connecter pour publier un commentaire.
Java prend en charge La Sérialisation Personnalisée. Lisez la section Personnaliser le Protocole par Défaut.
Citer:
Dans cette méthode, ce que vous pourriez faire est de sérialiser dans d'autres formes si vous avez besoin tels que la liste de tableaux pour l'Emplacement que vous illustrés ou JSON ou d'un autre format des données/méthode et de le reconstruire à l'arrière sur les méthodes readObject()
Avec votre exemple, vous ajoutez le code suivant:
writeObject
. Que ferais-je d'ajouter correctement de la Liste pour la sérialisation?oos.writeObject(loc)
je peux faireois.readObject()
, que vous semblez avoir omis.ArrayList
ou objet JSON ou quoi que ce soit. Vous pourriez faireoos.writeInt(x); oos.writeInt(y); ...
et les méthodes d'entrée dans le même ordre.assumes "static java.util.Date aDate;" declared
peu pour?defaultWriteObject()
etdefaultReadObject()
est toujours appelé en premier - et l'ordre est le même pour la lecture et l'écriture; il n'y a pas de "renversement" nécessaire, comme on le fait dans un flux d'octets traitées dans un réseau de protocole de transport. L'autre aspect est que ces deux méthodes sont à la fois privé et ne peut être appelée que par la JVM (et encore, la sérialisation de l'API exposées à l'appel de la méthode restent inchangés).Similaire à @momo de répondre, mais sans l'aide d'une Liste et d'auto-coffret int les valeurs qui font qu'il est beaucoup plus compact.
writeObject
à la place. J'ai accepté momo de la réponse, car elle a été la première, mais pour la situation donnée, cela peut être une meilleure réponse.Si elle doit être la sérialisation Java, la seule façon que je connaisse est de redéfinir la
readObject()
etwriteObject()
dans toutes les classes ayant une référence à une instance deLocation
comme indiqué dans la réponse de Momo. Notez que cela ne vous permettra pas de sérialiser unLocation[]
, et vous obliger à la sous-classe tousCollection<Location>
figurant dans votre code. En outre, il exige que les champs de typeLocation
être marqué transitoire, ce qui permettra d'exclure leurs définitions sur la sérialisation des flux, de la possible de déjouer la détection de l'incompatibilité des changements de classe.Une meilleure façon serait de simplement remplacer
ObjectOutputStream.writeObject
. Hélas, cette méthode estfinal
. Vous pourriez remplacerObjectOutputStream.writeObjectOverride()
à la place, mais cette méthode ne peut pas déléguer la mise en œuvre par défaut,ObjectOutputStream.writeObject0()
, car cette méthode estprivate
. Bien sûr, vous pouvez appeler la méthode privée à l'aide de la réflexion, mais ...Par conséquent, je vous recommandons de vérifier vos contraintes. A-t-elle à la sérialisation Java? Pouvez-vous vraiment pas changer la définition de la classe
Location
?Si vous avez le code source de la classe
Location
, il est assez facile d'ajouterimplements Serializable
et l'ajouter à votre classpath. Oui, vous aurez à le faire à nouveau en cas de mise à niveau de la bibliothèque, mais il pourrait être mieux que l'alternative ...