Réponses:
Le transient
mot-clé en Java est utilisé pour indiquer qu'un champ ne doit pas faire partie du processus de sérialisation (ce qui signifie enregistré, comme dans un fichier).
D'après les spécifications du langage Java, Java SE 7 Edition , Section 8.3.1.3. transient
Champs :
Les variables peuvent être marquées
transient
pour indiquer qu'elles ne font pas partie de l'état persistant d'un objet.
Par exemple, vous pouvez avoir des champs qui sont dérivés d'autres champs et ne doivent être effectués que par programme, plutôt que de conserver l'état via la sérialisation.
Voici une GalleryImage
classe qui contient une image et une vignette dérivée de l'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 générée en appelant la generateThumbnail
méthode.
Le thumbnailImage
champ est marqué comme transient
, donc seul l'original image
est sérialisé plutôt que de conserver l'image d'origine et l'image miniature. Cela signifie que moins de stockage serait nécessaire pour enregistrer l'objet sérialisé. (Bien sûr, cela peut être souhaitable ou non en fonction des exigences du système - ce n'est qu'un exemple.)
Au moment de la désérialisation, la readObject
méthode est appelée pour effectuer toutes les opérations nécessaires pour restaurer l'état de l'objet à l'état auquel la sérialisation s'est produite. Ici, la vignette doit être générée, la readObject
méthode est donc remplacée afin que la vignette soit générée en appelant la generateThumbnail
méthode.
Pour plus d'informations, l'article Découvrez les secrets de l'API Java Serialization (qui était à l'origine disponible sur Sun Developer Network) comporte une section qui traite de l'utilisation et présente un scénario dans lequel le transient
mot clé est utilisé pour empêcher la sérialisation de certains champs.
Avant de comprendre le transient
mot - clé, il faut comprendre le concept de sérialisation. Si le lecteur connaît la sérialisation, veuillez ignorer le premier point.
La sérialisation est le processus qui rend 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, le stockage d'octets dans un fichier) ou le transfert (par exemple, l'envoi d'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 d'octets. C'est l'un des concepts importants de la programmation Java car la sérialisation est principalement utilisée dans la programmation réseau. Les objets qui doivent être transmis via le réseau doivent être convertis en octets. À cette fin, chaque classe ou interface doit implémenter l' Serializable
interface. Il s'agit d'une interface de marqueur sans aucune méthode.
transient
mot - clé et son but?Par défaut, toutes les variables de l'objet sont converties dans un état persistant. Dans certains cas, vous souhaiterez peut-être éviter de persister certaines variables car vous n'avez pas besoin de les conserver. Vous pouvez donc déclarer ces variables comme transient
. Si la variable est déclarée comme transient
, elle ne sera pas persistante. C'est le but principal du transient
mot - clé.
Je veux expliquer les deux points ci-dessus avec l'exemple suivant:
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
Le deuxième prénom est déclaré comme transient
, il ne sera donc pas stocké dans le stockage persistant.
NameFormatter
habitude de conduire toString()
. Ou tout autre élément lié à la configuration, à l'affichage ou à la logique métier, ... par opposition aux données.
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 d'usine 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.
Ma petite contribution:
Qu'est-ce qu'un champ transitoire?
Fondamentalement, tout champ modifié avec le transient
mot-clé est un champ transitoire.
Pourquoi les champs transitoires sont-ils nécessaires en Java?
Le transient
mot clé 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 conserver les objets Java, principalement afin que leurs états puissent être conservés lorsqu'ils sont transférés ou inactifs. Parfois, il est logique de ne pas sérialiser certains attributs d'un objet.
Quels champs devez-vous marquer comme transitoires?
Nous savons maintenant le but de latransient
mots-clés et champs transitoires, il est important de savoir quels champs marquer comme transitoires. Les champs statiques ne sont pas sérialisés non plus, donc le mot-clé correspondant ferait aussi l'affaire. Mais cela pourrait ruiner la conception de votre classe; c'est là que le transient
mot - clé vient à la rescousse. J'essaie de ne pas permettre la sérialisation des champs dont les valeurs peuvent être dérivées des autres, alors 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 avec le nombre de mots d'article. Si vous enregistrez un article entier, il n'est vraiment pas nécessaire d'enregistrer le nombre de mots, car il peut être calculé lorsque l'article est "désérialisé". Ou pensez aux bûcherons;Logger
les instances n'ont presque jamais besoin d'être sérialisées, elles peuvent donc devenir transitoires.
transient
transient
Une transient
variable est une variable qui ne peut pas être sérialisée.
Un exemple où cela peut être utile qui vient à l'esprit est, les 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 à la null
place afin que vous puissiez les réinitialiser avec des données utiles en cas de besoin.
transient
est utilisé pour indiquer qu'un champ de classe n'a pas besoin d'être sérialisé. Le meilleur exemple est probablement un Thread
champ. Il n'y a généralement aucune raison de sérialiser un Thread
, car son état est très «spécifique au flux».
A
référence à une classe non sérialisable B
(comme Thread
dans votre exemple), alors A
doit soit marquer la référence comme transient
XOR doit remplacer le processus de sérialisation par défaut afin de faire quelque chose de raisonnable avec B
XOR supposer que seules les sous-classes sérialisables de B
sont réellement référencées (donc la sous-classe réelle doit prendre soin de son "mauvais" parent B
) XOR accepte que la sérialisation échoue. Dans un seul cas (marqué comme transitoire) B
est automatiquement et silencieusement ignoré.
Les systèmes de sérialisation autres que Java natif peuvent également utiliser ce modificateur. Hibernate, par exemple, ne conservera pas les champs marqués avec @Transient ou le modificateur transitoire . La terre cuite respecte également ce modificateur.
Je crois que la signification figurative du modificateur est "ce champ est destiné à un usage en mémoire uniquement. Ne persistez pas et ne le déplacez pas en dehors de cette machine virtuelle particulière. Son non portable". c'est-à-dire que vous ne pouvez pas compter sur sa valeur dans un autre espace mémoire VM. Tout comme volatile signifie que vous ne pouvez pas vous fier à certaines sémantiques de mémoire et de thread.
transient
ce ne serait pas un mot-clé s'il était conçu en ce moment. Ils utiliseraient probablement une annotation.
Parce que toutes les variables ne sont pas de nature sérialisable
Avant de répondre à cette question, je dois vous expliquer la SÉRIALISATION , car si vous comprenez ce que signifie la sérialisation en informatique scientifique, vous pouvez facilement comprendre ce mot-clé.
Sérialisation
Lorsqu'un objet est transféré via le réseau / enregistré sur un support physique (fichier, ...), l'objet doit être "sérialisé". La sérialisation convertit la série d'objets d'état d'octet. Ces octets sont envoyés sur le réseau / enregistrés et l'objet est recréé à partir de ces octets.
Exemple
public class Foo implements Serializable
{
private String attr1;
private String attr2;
...
}
Maintenant, SI VOUS VOULEZ NE PAS TRANSFÉRER / ENREGISTRER le champ de cet objet SO , vous pouvez utiliser le mot-clé transient
private transient attr2;
Il est nécessaire lorsque vous ne souhaitez pas partager certaines données sensibles associées à la sérialisation.
Thread
(crédit à @AH par exemple), auquel cas vous le marquerez comme transitoire. Cependant, un thread n'est pas une donnée sensible en soi, il n'est tout simplement pas logique de le sérialiser (et il n'est pas sérialisable).
Selon la signification transitoire de Google == qui ne dure que peu de temps; transitoire.
Maintenant, si vous voulez rendre quelque chose de transitoire en java, utilisez un mot-clé transitoire.
Q: où utiliser les transitoires?
R: Généralement, en Java, nous pouvons enregistrer des données dans des fichiers en les acquérant dans des variables et en écrivant ces variables dans des fichiers, ce processus est connu sous le nom de sérialisation. Maintenant, si nous voulons éviter que des données variables soient écrites dans un fichier, nous rendrons cette variable transitoire.
transient int result=10;
Remarque: les variables transitoires ne peuvent pas être locales.
Autrement dit, le mot-clé java transitoire protège les champs de la série Serialize en tant que contre-parties des champs non transitoires.
Dans cet extrait de code, notre classe abstraite BaseJob implémente l'interface Serializable, nous étendons de BaseJob mais nous n'avons pas besoin de sérialiser les sources de données distantes et locales; sérialiser uniquement les champs organizationName et isSynced.
public abstract class BaseJob implements Serializable{
public void ShouldRetryRun(){}
}
public class SyncOrganizationJob extends BaseJob {
public String organizationName;
public Boolean isSynced
@Inject transient RemoteDataSource remoteDataSource;
@Inject transient LocalDaoSource localDataSource;
public SyncOrganizationJob(String organizationName) {
super(new
Params(BACKGROUND).groupBy(GROUP).requireNetwork().persist());
this.organizationName = organizationName;
this.isSynced=isSynced;
}
}
Exemple de code simplifié pour mot-clé transitoire.
import java.io.*;
class NameStore implements Serializable {
private String firstName, lastName;
private transient String fullName;
public NameStore (String fName, String lName){
this.firstName = fName;
this.lastName = lName;
buildFullName();
}
private void buildFullName() {
// assume building fullName is compuational/memory intensive!
this.fullName = this.firstName + " " + this.lastName;
}
public String toString(){
return "First Name : " + this.firstName
+ "\nLast Name : " + this.lastName
+ "\nFull Name : " + this.fullName;
}
private void readObject(ObjectInputStream inputStream)
throws IOException, ClassNotFoundException
{
inputStream.defaultReadObject();
buildFullName();
}
}
public class TransientExample{
public static void main(String args[]) throws Exception {
ObjectOutputStream o = new ObjectOutputStream(new FileOutputStream("ns"));
o.writeObject(new NameStore("Steve", "Jobs"));
o.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("ns"));
NameStore ns = (NameStore)in.readObject();
System.out.println(ns);
}
}
Un champ qui est déclaré avec un modificateur transitoire ne participera pas au processus sérialisé. Lorsqu'un objet est sérialisé (enregistré dans n'importe quel état), les valeurs de ses champs transitoires sont ignorées dans la représentation série, tandis que le champ autre que les champs transitoires participera au processus de sérialisation. C'est le but principal du mot-clé transitoire.
@DoNotSerialize
?