Why does Java have transient fields?

前端 未结 15 1954
旧时难觅i
旧时难觅i 2020-11-22 03:54

Why does Java have transient fields?

相关标签:
15条回答
  • 2020-11-22 04:25

    The transient keyword in Java is used to indicate that a field should not be part of the serialization (which means saved, like to a file) process.

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

    Variables may be marked transient to indicate that they are not part of the persistent state of an object.

    For example, you may have fields that are derived from other fields, and should only be done so programmatically, rather than having the state be persisted via serialization.

    Here's a GalleryImage class which contains an image and a thumbnail derived from the 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();
        }    
    }
    

    In this example, the thumbnailImage is a thumbnail image that is generated by invoking the generateThumbnail method.

    The thumbnailImage field is marked as transient, so only the original image is serialized rather than persisting both the original image and the thumbnail image. This means that less storage would be needed to save the serialized object. (Of course, this may or may not be desirable depending on the requirements of the system -- this is just an example.)

    At the time of deserialization, the readObject method is called to perform any operations necessary to restore the state of the object back to the state at which the serialization occurred. Here, the thumbnail needs to be generated, so the readObject method is overridden so that the thumbnail will be generated by calling the generateThumbnail method.

    For additional information, the Discover the secrets of the Java Serialization API article (which was originally available on the Sun Developer Network) has a section which discusses the use of and presents a scenario where the transient keyword is used to prevent serialization of certain fields.

    0 讨论(0)
  • 2020-11-22 04:25

    Serialization systems other than the native java one can also use this modifier. Hibernate, for instance, will not persist fields marked with either @Transient or the transient modifier. Terracotta as well respects this modifier.

    I believe the figurative meaning of the modifier is "this field is for in-memory use only. don't persist or move it outside of this particular VM in any way. Its non-portable". i.e. you can't rely on its value in another VM memory space. Much like volatile means you can't rely on certain memory and thread semantics.

    0 讨论(0)
  • 2020-11-22 04:25

    Simplified example code for transient-keyword.

    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 04:26

    It's needed when you don't want to share some sensitive data that go with serialization.

    0 讨论(0)
  • 2020-11-22 04:27

    transient is used to indicate that a class field doesn't need to be serialized. Probably the best example is a Thread field. There's usually no reason to serialize a Thread, as its state is very 'flow specific'.

    0 讨论(0)
  • 2020-11-22 04:29

    Because not all variables are of a serializable nature.

    1. Serialization and Deserialization are symmetry processes, if not you can't expect the result to be determined, in most cases, undetermined values are meaningless;
    2. Serialization and Deserialization are idempotent, it means you can do serialization as many time as you want, and the result is the same.

    So if the Object can exists on memory but not on disk, then the Object can't be serializable, because the machine can't restore the memory map when deserialization. Fro example, you can't serialize a Stream object.

    You can not serialize a Connection object, because it's state also dependent on the remote site.

    0 讨论(0)
提交回复
热议问题