Est-il possible d'avoir des champs final transient
qui ont une valeur autre que celle par défaut après la sérialisation en Java? Mon usecase est une variable de cache - c'est pourquoi c'est transient
. J'ai également l'habitude de faire des champs Map
qui ne seront pas changés (c'est-à-dire que le contenu de la carte est changé, mais l'objet lui-même reste le même) final
. Cependant, ces attributs semblent être contradictoires - alors que le compilateur permet une telle combinaison, je ne peux pas mettre le champ à autre chose que null
après la désérialisation.champs transitoires définitifs et sérialisation
J'ai essayé ce qui suit, sans succès:
- simple, l'initialisation du champ (dans l'exemple): ce que je fais normalement, mais l'initialisation ne semble pas se produire après délinéarisation;
- initialisation dans le constructeur (je crois que c'est sémantiquement le même que ci-dessus);
- Affectation du champ dans
readObject()
- impossible car le champ estfinal
.
Dans l'exemple cache
est public
uniquement pour le test.
import java.io.*;
import java.util.*;
public class test
{
public static void main (String[] args) throws Exception
{
X x = new X();
System.out.println (x + " " + x.cache);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
new ObjectOutputStream (buffer).writeObject (x);
x = (X) new ObjectInputStream (new ByteArrayInputStream (buffer.toByteArray())).readObject();
System.out.println (x + " " + x.cache);
}
public static class X implements Serializable
{
public final transient Map <Object, Object> cache = new HashMap <Object, Object>();
}
}
Sortie:
[email protected] {}
[email protected] null
Merci. Je m'en doutais, mais je ne savais pas que je n'avais pas manqué quelque chose. – doublep
Votre réponse «les transitoires ne peuvent pas être définitifs» est incorrecte: veuillez expliquer le code source d'Hibernate avec «final transitoire» partout: https://github.com/hibernate/hibernate-orm/blob/4.3.7.Final/hibernate- core/src/main/java/org/hibernate/interne/SessionFactoryImpl.java –
En fait, la réponse est fausse. Les champs "transitoires" peuvent être "finaux". Mais pour que cela fonctionne pour autre chose que les valeurs par défaut ('false' /' 0'/'0.0' /' null'), vous voulez implémenter non seulement 'readObject()' mais aussi 'readResolve()', ou utilisez * Reflection *. –