Pourquoi Java ont transitoire champs?

pourquoi Java a-t-il des champs transitoire ?

1224
demandé sur RAnders00 2009-05-26 16:11:36

13 réponses

le mot-clé transient en Java est utilisé pour indiquer qu'un champ ne doit pas être sérialisé.

From the Java Language Specification, Java SE 7 Edition , Section 8.3.1.3. transient Champs :

les Variables peuvent être marquées transient à indiquent qu'ils ne font pas partie de la l'état persistant d'un objet.

pour exemple, vous pouvez avoir des champs qui sont issues d'autres champs, et ne doit être fait par programmation, plutôt que d'avoir l'état a persisté par la sérialisation.

Voici une classe GalleryImage qui contient une image et une vignette dérivées 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, thumbnailImage est une image miniature générée en invoquant la méthode generateThumbnail .

le thumbnailImage le champ est marqué comme transient , de sorte que seul l'original image est sérialisé plutôt que de persister à la fois l'image originale et l'image miniature. Cela signifie que moins de stockage serait nécessaire pour sauver l'objet sérialisé. (Bien sûr, cela peut être souhaitable ou non selon les exigences du système -- ce n'est qu'un exemple.)

au moment de la désérialisation, la méthode readObject est appelé à effectuer toute opérations nécessaires pour restaurer l'état de l'objet à l'état où la sérialisation s'est produite. Ici, la vignette doit être générée, de sorte que la méthode readObject est annulée afin que la vignette soit générée en appelant la méthode generateThumbnail .

pour plus d'informations, L'article Discover the secrets of the Java Serialization API (qui était à l'origine disponible sur le réseau Sun Developer) a une section qui traite de l'utilisation et présente un scénario où le mot-clé transient est utilisé pour empêcher la sérialisation de certains champs.

1442
répondu coobird 2013-07-05 06:19:33

avant de comprendre le mot-clé transient , il faut comprendre le concept de sérialisation. Si le lecteur est au courant de la sérialisation, veuillez sauter le premier point.

Qu'est-ce que la sérialisation?

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 et stockées dans un fichier. De la même manière, nous pouvons utiliser la désérialisation de ramener le l'objet de l'état d'octets. C'est l'un des concepts importants de la programmation Java car la sérialisation est surtout utilisée dans la programmation réseau. Les objets qui doivent être transmis par le réseau doivent être convertis en octets. À cette fin, chaque classe ou interface doit mettre en œuvre l'interface Serializable . Il s'agit d'une interface marqueur sans aucune méthode.

maintenant, qu'est-ce que le mot-clé transient et son but?

par défaut, toutes les variables de l'objet sont converties en un état persistant. Dans certains cas, vous pouvez vouloir éviter de persister certaines variables parce que vous n'avez pas le besoin de persister ces variables. 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 le but principal du mot-clé transient .

je veux expliquer les deux points ci-dessus avec le suivant exemple:

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

Middle Name est déclaré comme transient , il ne sera donc pas stocké dans le stockage persistant.

Source

366
répondu Rahul Saxena 2016-01-31 17:20:04

Pour vous permettre de définir des variables que vous ne voulez pas serialise.

dans un objet, vous pouvez avoir des informations que vous ne voulez pas sérialiser/persister (peut-être une référence à un objet parent factory), ou peut-être que cela n'a pas de sens de sérialiser. Le fait de les marquer comme "transitoires" signifie que le mécanisme de sérialisation ignorera ces champs.

80
répondu Brian Agnew 2012-03-19 12:44:15

ma petite contribution:

Qu'est-ce qu'un champ transitoire?

Fondamentalement, tout champ modifié avec le mot-clé transient est un champ transitoire.



pourquoi les champs transitoires sont-ils nécessaires en Java?

Le mot-clé transient vous donne un certain contrôle sur le processus de sérialisation et vous permet d'exclure certains les propriétés de l'objet de ce processus. Le processus de sérialisation est utilisé pour persister les objets Java, principalement pour que leurs États puissent être préservés pendant qu'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 "transitoire"?

Maintenant que nous connaissons le but du mot-clé transient et les champs transitoires, c'est important pour savoir quels champs marquer transitoire. Les champs statiques ne sont pas sérialisés non plus, donc le mot-clé correspondant ferait aussi l'affaire. Mais cela pourrait ruiner votre dessin de classe; c'est là que le mot-clé transient vient à la rescousse. J'essaie de ne pas laisser les champs dont les valeurs peuvent être dérivées des autres être sérialisés, donc je les marque transitoires. Si vous avez un champ appelé interest dont la valeur peut être calculée à partir d'autres champs ( principal , rate & time ), il n'y a pas besoin pour sérialiser.



Un autre bon exemple est l'article word counts. Si vous sauvegardez un article entier, il n'y a vraiment pas besoin de sauvegarder le nombre de mots, parce qu'il peut être calculé lorsque l'article obtient "deserialized."Ou pensez-enregistreurs; Logger cas presque jamais besoin d'être sérialisé, de sorte qu'ils peuvent être faits de façon transitoire.

28
répondu Shreyos Adikari 2018-08-21 16:46:02

Un transient la variable est une variable qui ne peut pas être sérialisé.

un exemple de quand cela pourrait être utile qui vient à l'esprit est, 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 à la place afin que vous puissiez les ré-initialiser avec des données utiles lorsque nécessaire.

21
répondu Adrian Grigore 2018-01-24 05:47:49

transient indique qu'un champ de classe n'a pas besoin d'être sérialisé. Le meilleur exemple est probablement un champ Thread . Il n'y a généralement aucune raison de sérialiser un Thread , car son état est très "spécifique au flux".

13
répondu Andrei Ciobanu 2013-11-26 22:53:52
Les systèmes de sérialisation

autres que le java natif peuvent également utiliser ce modificateur. L'hibernation, par exemple, ne persistera pas dans les champs marqués d'un modificateur @transitoire ou transitoire . Terracotta respecte également ce modificateur.

je crois que le sens figuratif du modificateur est" ce champ est réservé à une utilisation en mémoire. ne persistez pas ou ne le déplacez pas hors de cette VM particulière de quelque manière que ce soit. Son non portable". c'est-à-dire que vous ne pouvez pas vous fier à sa valeur dans un autre espace mémoire VM. Un peu comme volatile signifie que vous ne pouvez pas compter sur une certaine sémantique de la mémoire et du fil.

10
répondu DragonFax 2009-05-28 02:20:46

parce que toutes les variables ne sont pas de nature sérialisable

9
répondu Silfverstrom 2009-05-26 12:15:38
La sérialisation

est le processus qui consiste à sauvegarder les États d'un objet dans un format persistant (tel que file stream ou database), puis à les restaurer à partir du flux (de-serialization). En Java, un objet d'une classe est sérialisable si la classe implémente java.io.Interface sérialisable. Il s'agit d'une interface marqueur qui indique à la JVM que la classe est éligible pour la sérialisation.

public class User implements Serializable {

    private static final long serialVersionUID = 1234L;

    private String username;
    private String email;
    private transient String password;
    private Date birthday;
    private int age;

    public User(String username, String email, String password, Date birthday,
            int age) {
        this.username = username;
        this.email = email;
        this.password = password;
        this.birthday = birthday;
        this.age = age;
    }

    public void printInfo() {
        System.out.println("username: " + username);
        System.out.println("email: " + email);
        System.out.println("password: " + password);
        System.out.println("birthday: " + birthday);
        System.out.println("age: " + age);
    }

    // getters and setters

}

il y a trois points importants dans ce modèle classe: Il doit implémenter l'interface sérialisable. Sinon, on va prendre un café.io.NotSerializableException en essayant de sérialiser un objet de la classe. Une constante nommée serialVersionUID est déclarée et assignée une valeur longue:

private static final long serialVersionUID = 1234L;

il s'agit d'une constante conventionnelle qui doit être déclarée lorsqu'une classe implémente l'interface sérialisable. La version série UID assure la compatibilité entre le sérialisé et le dé-sérialisé versions d'objets d'une classe, parce que le processus de sérialisation et de dé-sérialisation peut se produire sur différents ordinateurs et systèmes. Bien que cette déclaration soit optionnelle, il est toujours recommandé de déclarer le serialVersionUID pour une classe serialisable.

notez que le champ Mot de passe est marqué comme transitoire:

private transient String password;

parce que nous ne voulons pas stocker le mot de passe lors de la sérialisation de l'objet. La règle est, quand une variable est marqué comme transitoire, son objet ne sera pas sérialisé pendant la sérialisation.

une variable transitoire est une variable qui ne peut pas être sérialisée. Vous utilisez le mot-clé transient pour indiquer à la machine virtuelle Java que la variable indiquée ne fait pas partie de l'état persistant de l'objet.

les modificateurs d'accès supportés par Java sont statiques, finaux, abstraits, synchronisés, natifs, volatiles, transitoires et strictfp.

le tableau suivant donne la liste des spécificateurs et modificateurs D'accès Java qui peuvent être appliqués aux variables, méthodes et classes.

SPECIFIER/MODIFIER  LOCAL VARIABLE  INSTANCEVARIABLE    METHOD   CLASS
public              NA              A                   A         A
protected           NA              A                   A         NA
default             A               A                   A         A
private             NA              A                   A         NA
final               A               A                   A         A
static              NA              A                   A         NA
synchronized        NA              NA                  A         NA
native              NA              NA                  A         NA
volatile            NA              A                   NA        NA
transient           NA              A                   NA        NA
strictfp            NA              NA                  A         A
9
répondu Zia 2015-12-22 08:20:30

avant de répondre à cette question, je dois vous expliquer le SERIALIZATION , parce que si vous comprenez ce que cela signifie serialization dans science computer, 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 octet de statut de l'objet de la série. Ces octets sont envoyés sur le network / saved 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 TRANSFERT / sauvé champ de cet objet SO , vous pouvez utiliser mot-clé transient

private transient attr2;

exemple

6
répondu BERGUIGA Mohamed Amine 2017-05-23 12:26:29

il est nécessaire lorsque vous ne voulez pas partager certaines données sensibles qui vont avec la sérialisation.

3
répondu setzamora 2009-05-26 12:19:31

comme sur google sens transitoire = = ne dure que peu de temps; impermanent.

maintenant si vous voulez faire quelque chose de transitoire en java utilisez le mot-clé de transition.

Q: Où utiliser transient?

A: 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 les données variables à écrire au fichier, Nous ferions cette variable est transitoire.

résultat transitoire int=10;

Note: les variables transitoires ne peuvent pas être locales.

1
répondu Mateen 2014-11-02 08:56:39

simplement dit, le mot-clé Java transitoire protège les champs de la sérialisation été comme leurs parties non-transitoires compteur de champs.

dans cet extrait de code notre classe abstraite BaseJob implement Serializable interface, nous nous étendons de BaseJob mais nous n'avons pas besoin de sérialiser les sources de données distantes et locales; serialize seulement organizationName et champs 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;

   }
}
1
répondu nyulan 2017-11-14 13:40:27