Comment fonctionne la sérialisation java désérialiser final champs lorsque aucun constructeur par défaut spécifié?
J'ai une classe définissant une valeur immuable type que j'ai maintenant besoin de sérialiser. L'immutabilité vient de la finale de champs qui sont définis dans le constructeur. J'ai essayé de la sérialisation, et il fonctionne (étonnamment?) - mais je n'ai aucune idée de comment.
Voici un exemple de la classe
public class MyValueType implements Serializable
{
private final int value;
private transient int derivedValue;
public MyValueType(int value)
{
this.value = value;
this.derivedValue = derivedValue(value);
}
//getters etc...
}
Étant donné que la classe n'ont pas non arg constructeur, comment peut-il être instancié et la finale de champ?
(Un côté - j'ai remarqué cette classe, en particulier parce que l'IDÉE n'était pas de la génération d'un "pas de serialVersionUID" inspection avertissement pour cette classe, pas encore réussi à produire des mises en garde pour les autres classes que je viens de sérialisable.)
Vous devez vous connecter pour publier un commentaire.
La désérialisation est mis en œuvre par la JVM sur un niveau en dessous de la langue de base des constructions. Plus précisément, il ne s'agit pas de tout constructeur.
Une certaine mauvaise magie noire qui se passe. Il y a une porte dérobée dans la machine qui permet à un objet d'être créé sans invoquer de tout constructeur. Les champs de la nouvelle de l'objet sont d'abord initialisé à leurs valeurs par défaut (false, 0, null, etc), et puis la désérialisation des objets code remplit les champs avec les valeurs du flux d'objet.
(Maintenant que Java est open source, vous pouvez lire le code qui fait cela ... et pleurer!)
Michael et Stephen vous a donné une excellente réponse, je veux juste vous mettre en garde sur
transient
champs.Si la valeur par défaut (
null
pour les références, 0 pour les primitives ) n'est pas acceptable pour eux après la désérialisation, alors vous devez fournir votre version dereadObject
et l'initialiser là.