Pourquoi Java a-t-il transitoire des champs ?
Mais pourquoi est-ce un mot-clé et non une annotation ? @DoNotSerialize
?
El transient
en Java est utilisé pour indiquer qu'un champ ne doit pas faire partie du processus de sérialisation (ce qui signifie qu'il doit être sauvegardé, comme dans un fichier).
De la Spécification du langage Java, édition Java SE 7 , Section 8.3.1.3. transient
Champs :
Les variables peuvent être marquées
transient
à pour indiquer qu'ils ne font pas partie de l'état état persistant d'un objet.
Par exemple, vous pouvez avoir des champs qui sont dérivés d'autres champs, et qui ne doivent être réalisés que par programmation, plutôt que de faire persister l'état par sérialisation.
Voici un GalleryImage
qui contient une image et une vignette dérivée de cette image :
class GalleryImage implements Serializable
{
private Image image;
private transient Image thumbnailImage;
private void generateThumbnail()
{
// Generate thumbnail.
}
private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
generateThumbnail();
}
}
Dans cet exemple, le thumbnailImage
est une image miniature qui est générée en invoquant la fonction generateThumbnail
méthode.
El thumbnailImage
Le champ est marqué comme transient
donc seul l'original image
est sérialisée plutôt que de persister à la fois l'image originale et l'image miniature. Cela signifie que moins de stockage serait nécessaire pour sauvegarder l'objet sérialisé. (Bien entendu, cela peut être souhaitable ou non en fonction des exigences du système - il s'agit simplement d'un exemple).
Au moment de la désérialisation, l'élément [readObject
](http://java.sun.com/javase/6/docs/api/java/io/ObjectInputStream.html#readObject()) est appelée pour effectuer toutes les opérations nécessaires pour restaurer l'état de l'objet à l'état dans lequel la sérialisation a eu lieu. Ici, la vignette doit être générée, donc la méthode readObject
est surchargée afin que la vignette soit générée en appelant la méthode generateThumbnail
méthode.
Pour plus d'informations, l'article Découvrez les secrets de l'API de sérialisation Java (qui était à l'origine disponible sur le Sun Developer Network) comporte une section qui discute de l'utilisation de l'outil et présente un scénario dans lequel l'outil transient
Le mot-clé est utilisé pour empêcher la sérialisation de certains champs.
Je trouve étrange que la sérialisation soit interne à Java. Il peut être implémenté comme une interface ou une classe abstraite qui exige que les utilisateurs surchargent les méthodes de lecture et d'écriture.
Avant de comprendre le transient
le mot-clé, il faut comprendre le concept de sérialisation. Si le lecteur connaît la sérialisation, veuillez sauter le premier point.
La sérialisation est le processus qui consiste à rendre l'état de l'objet persistant. Cela signifie que l'état de l'objet est converti en un flux d'octets à utiliser pour la persistance (par exemple, stocker des octets dans un fichier) ou le transfert (par exemple, envoyer des octets sur un réseau). De la même manière, nous pouvons utiliser la désérialisation pour ramener l'état de l'objet à partir des octets. C'est l'un des concepts importants de la programmation Java, car la sérialisation est surtout utilisée dans la programmation de réseaux. Les objets qui doivent être transmis par le réseau doivent être convertis en octets. Pour cela, chaque classe ou interface doit implémenter la fonction Serializable
interface. Il s'agit d'une interface de marquage sans aucune méthode.
transient
mot-clé et son objectif ?Par défaut, toutes les variables de l'objet sont converties en un état persistant. Dans certains cas, vous pouvez éviter de persister certaines variables parce que vous n'en avez pas besoin. Vous pouvez donc déclarer ces variables comme transient
. Si la variable est déclarée comme transient
alors elle ne sera pas persistée. C'est l'objectif principal du transient
mot-clé.
Je veux expliquer les deux points ci-dessus avec l'exemple suivant (emprunté à cet article ):
package javabeat.samples; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; class NameStore implements Serializable{ private String firstName; private transient String middleName; private String lastName; public NameStore (String fName, String mName, String lName){ this.firstName = fName; this.middleName = mName; this.lastName = lName; } public String toString(){ StringBuffer sb = new StringBuffer(40); sb.append("First Name : "); sb.append(this.firstName); sb.append("Middle Name : "); sb.append(this.middleName); sb.append("Last Name : "); sb.append(this.lastName); return sb.toString(); } } public class TransientExample{ public static void main(String args[]) throws Exception { NameStore nameStore = new NameStore("Steve", "Middle","Jobs"); ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("nameStore")); // writing to object o.writeObject(nameStore); o.close(); // reading from object ObjectInputStream in = new ObjectInputStream(new FileInputStream("nameStore")); NameStore nameStore1 = (NameStore)in.readObject(); System.out.println(nameStore1); } }
Et la sortie sera la suivante :
First Name : Steve Middle Name : null Last Name : Jobs
Deuxième prénom est déclaré comme transient
Il ne sera donc pas stocké dans le stockage persistant.
Cet exemple est tiré de ce code, vous pouvez le lire ici : javabeat.net/2009/02/qu'est-ce qu'un mot-clé transitoire en Java ?
Cette partie me semble étrange et peut prêter à confusion : "Cela signifie que l'état de l'objet est converti en un flux d'octets et stocké dans un fichier ". Il me semble que la plupart du temps, la sérialisation n'implique pas l'écriture dans un fichier (exemple : les exemples de réseau qui suivent).
L'exemple est mauvais, puisque le deuxième prénom est clairement no une propriété transitoire.
Pour vous permettre de définir des variables que vous ne voulez pas sérialiser.
Dans un objet, vous pouvez avoir des informations que vous ne voulez pas sérialiser/persister (peut-être une référence à un objet de fabrique parent), ou peut-être que cela n'a pas de sens de sérialiser. En les marquant comme "transitoires", le mécanisme de sérialisation ignorera ces champs.
Pourquoi les champs transitoires sont-ils nécessaires en Java ?
El transient
vous donne un certain contrôle sur le processus de sérialisation et vous permet d'exclure certaines propriétés d'objet de ce processus. Le processus de sérialisation est utilisé pour faire persister les objets Java, principalement pour que leurs états puissent être préservés pendant leur transfert ou leur inactivité. Parfois, il est judicieux de ne pas sérialiser certains attributs d'un objet.
Quels sont les champs que vous devez marquer comme transitoires ?
Maintenant que nous connaissons le but de la transient
et les champs transitoires, il est important de savoir quels sont les champs à marquer comme transitoires. Les champs statiques ne sont pas sérialisés non plus, donc le mot-clé correspondant ferait également l'affaire. Mais cela pourrait ruiner la conception de votre classe ; c'est ici que le mot-clé transient
vient à la rescousse. J'essaie de ne pas autoriser la sérialisation des champs dont les valeurs peuvent être dérivées d'autres champs, c'est pourquoi je les marque comme transitoires. Si vous avez un champ appelé interest
dont la valeur peut être calculée à partir d'autres champs ( principal
, rate
& time
), il n'est pas nécessaire de le sérialiser.
Un autre bon exemple est celui du nombre de mots des articles. Si vous sauvegardez un article entier, il n'est pas vraiment nécessaire de sauvegarder le nombre de mots, car il peut être calculé lorsque l'article est "désérialisé". Ou pensez aux enregistreurs ; Logger
n'ont presque jamais besoin d'être sérialisées, elles peuvent donc être rendues transitoires.
Votre "phrase simple" n'est qu'une tautologie. Elle n'explique rien. Vous feriez mieux de vous en passer.
A transient
est une variable qui n'est pas incluse lorsque la classe est sérialisée.
Un exemple d'utilité qui me vient à l'esprit est celui des variables qui n'ont de sens que dans le contexte d'une instance d'objet spécifique et qui deviennent invalides une fois que vous avez sérialisé et désérialisé l'objet. Dans ce cas, il est utile que ces variables deviennent null
afin que vous puissiez les réinitialiser avec des données utiles lorsque cela est nécessaire.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.