Why does Java have transient fields?
Asked Answered
K

15

1652

Why does Java have transient fields?

Kizzykjersti answered 26/5, 2009 at 12:11 Comment(1)
So That They Won't Be Serialized.Calaboose
P
1826

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 article Discover the secrets of the Java Serialization API (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.

Purvis answered 26/5, 2009 at 12:53 Comment(15)
But why is it a keyword, and not an annotation @DoNotSerialize?Greig
I guess, this is owned to a time when there were no annotations in Java.Serena
I find it odd that serializable is internal to Java. It can be implemented as an interface or abstract class that requires users to override the read and write methods.Client
readObject method is called automatically or we should call it?Pico
@MJafar: readObject is usually chained into deserialization mechanisms and thus called automatically. Furthermore, in many cases you do not need to override it - the default implementation does the trick.Dearly
@Client probably because dealing with binary formats yourself is incredibly painful in Java due to the lack of unsigned integers.Twilatwilight
@ElazarLeibovich I think is because this keyword is older than the annotations: en.wikipedia.org/wiki/Java_annotation#HistoryDanyelledanyette
Note that XML serialization in Java ignores this keyword for some reason.Eichler
Why I can set transient on an instance variable of a class when this class doesn't implement the Serializable interface? This makes no sense...Thermodynamics
@Thermodynamics A child class could implement SerializableOstracism
@novaterata: when a Serializable child class extends a non-Serializable class, the child class becomes responsible for storing and restoring all relevant state of its superclass(es) (and the superclass must have an accessible no-arg constructor). Therefore, transient modifiers on the non-Serializable superclass’ fields still have no relevance then. But the language specification doesn’t forbid using transient for storage mechanisms other than Serialization.Tanah
why Serializable interface is market don't include readResolve,writeObject etc. because sub class and also super class's readResolve,writeObject etc. methods must be invoked by jvm.If it were overridable then super class's readResolve method could not be invokedSomnambulate
@Client It isn't 'internal to Java', it is part of an API, and it is implemented as an interface. Your point escapes me.Calaboose
The default serializer can access parent classes using unsafe operations/ using native code. So the transient keyword is used when you use the default java serialization. Useful to send class state in RMI or in a custom binary over REST/http implementation. Faster than json/ xml transformers.Koralle
@caleb: After many years, Oracle agrees with you - they want to drop serialization: infoworld.com/article/3275924/java/…Deherrera
P
496

Before understanding the transient keyword, one has to understand the concept of serialization. If the reader knows about serialization, please skip the first point.

What is serialization?

Serialization is the process of making the object's state persistent. That means the state of the object is converted into a stream of bytes to be used for persisting (e.g. storing bytes in a file) or transferring (e.g. sending bytes across a network). In the same way, we can use the deserialization to bring back the object's state from bytes. This is one of the important concepts in Java programming because serialization is mostly used in networking programming. The objects that need to be transmitted through the network have to be converted into bytes. For that purpose, every class or interface must implement the Serializable interface. It is a marker interface without any methods.

Now what is the transient keyword and its purpose?

By default, all of object's variables get converted into a persistent state. In some cases, you may want to avoid persisting some variables because you don't have the need to persist those variables. So you can declare those variables as transient. If the variable is declared as transient, then it will not be persisted. That is the main purpose of the transient keyword.

I want to explain the above two points with the following example (borrowed from this 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);
    }
}

And the output will be the following:

First Name : Steve
Middle Name : null
Last Name : Jobs

Middle Name is declared as transient, so it will not be stored in the persistent storage.

Peroxide answered 26/5, 2009 at 12:11 Comment(7)
This example is taken from this code, you can read it here:javabeat.net/2009/02/what-is-transient-keyword-in-javaGrassland
This part strikes me as odd and possibly confusing: "That means the state of the object is converted into a stream of bytes and stored in a file". It seems to me that most of the time serialization does not involve writing to a file (case in point: the networking examples that follow)Diazine
The example is a bad one, since the middle name is clearly not a transient property.Youngran
@Youngran For me, the example is helpful and at least explains the concept. Would you provide any better example if you are aware off?Pulitzer
@Yoda We could have a reference to a NameFormatter used to drive toString(). Or anything else related to configuration, or viewing, or business logic, ... as opposed to data.Youngran
@Youngran - A practical example would be In a LinkedList size could be a transient variable as it could be recalculated by after deserializing the object.Tussle
Thank you for the clear explanation with example, appreciate!Abomination
J
91

To allow you to define variables that you don't want to serialize.

In an object you may have information that you don't want to serialize/persist (perhaps a reference to a parent factory object), or perhaps it doesn't make sense to serialize. Marking these as 'transient' means the serialization mechanism will ignore these fields.

Jevons answered 26/5, 2009 at 12:13 Comment(0)
L
41

Why are transient fields needed in Java?

The transient keyword gives you some control over the serialization process and allows you to exclude some object properties from this process. The serialization process is used to persist Java objects, mostly so that their states can be preserved while they are transferred or inactive. Sometimes, it makes sense not to serialize certain attributes of an object.

Which fields should you mark transient?

Now that we know the purpose of the transient keyword and transient fields, it's important to know which fields to mark transient. Static fields aren't serialized either, so the corresponding keyword would also do the trick. But this might ruin your class design; this is where the transient keyword comes to the rescue. I try not to allow fields whose values can be derived from others to be serialized, so I mark them transient. If you have a field called interest whose value can be calculated from other fields (principal, rate & time), there is no need to serialize it.

Another good example is with article word counts. If you are saving an entire article, there's really no need to save the word count, because it can be computed when article gets "deserialized." Or think about loggers; Logger instances almost never need to be serialized, so they can be made transient.

Lawn answered 18/3, 2014 at 22:4 Comment(5)
Your 'simple sentence' is merely a tautology. It explains nothing. You'd be better off without it.Calaboose
This is a good explanation where the field should be transientPulitzer
interest field and word counts are good examples of transient fields.Tussle
Another good use case: If your object has components like sockets and if you would want to serialize then what happens to the socket? If would persist, after you deserialize what would the socket be holding? It makes sense to make that socket object as transientGild
The only thing left out of which fields should be marked transient is classes that literally can't be serialized, for any reason. As already mentioned, it may be a Socket, or some other type of session storage, or simply a class that doesn't allow serialization - the point being, aside times where it's not necessary to serialize a field, there's times where it's actively disallowed, and transient becomes a requirement for the class of interest to be serialized. Also, Logger instances tend to be static, and therefore don't need to be transient in the first placeNicollenicolson
H
34

A transient variable is a variable that isn't included when the class is serialized.

One example of when this might be useful that comes to mind is, variables that make only sense in the context of a specific object instance and which become invalid once you have serialized and deserialized the object. In that case it is useful to have those variables become null instead so that you can re-initialize them with useful data when needed.

Hedveh answered 26/5, 2009 at 12:15 Comment(1)
yeah, some thing like "password or crediCardPin" field members of a class.Falco
C
18

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.

Canopus answered 28/5, 2009 at 2:20 Comment(1)
I think that transient wouldn't be a keyword if it were designed at this time. They'd probably use an annotation.Designate
C
17

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'.

Caplin answered 26/3, 2010 at 14:16 Comment(4)
Correct me if I'm wrong, but Thread is not serializable so it will be skipped anyways?Discern
@TFennis: If a serializable class A references a not serializable class B (like Thread in your example), then A must either mark the reference as transient XOR must override the default serialization process in order to do something reasonable with B XOR assume that only serializable subclasses of B are actually referenced (so the actual subclass must take care for their "bad" parent B) XOR accept that the serialization will fail. In only one case (marked as transient) B is automatically and silently skipped.Infold
@Discern No, it will cause an exception.Calaboose
@A.H.: Why XOR? I would think code that did any combination of those things would work, and some combinations might be useful (e.g. overriding the default serialization process may be useful even if only serializable subclasses of B are referenced, and vice versa).Geordie
L
9

Before I respond to this question, I need to explain serialization, because if you understand what it means serialization in science computer you can easily understand this keyword.

When an object is transferred through the network / saved on physical media(file,...), the object must be "serialized". Serialization converts byte status object series. These bytes are sent on the network/saved and the object is re-created from these bytes.

Example:

public class Foo implements Serializable 
{
 private String attr1;
 private String attr2;
 ...
}

Now, if there's a field in this class you don't want to transfer or save, you can use the transient keyword

private transient attr2;

This prevents the field form being included when the class is serialized.

Locate answered 1/7, 2015 at 13:12 Comment(1)
Why would an object be transferred through the network? Can you give an example?Dionysiac
N
7

Because not all variables are of a serializable nature

Nanete answered 26/5, 2009 at 12:15 Comment(1)
Please provide more information when you give an answer.Hoxie
D
5

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

Dunnage answered 26/5, 2009 at 12:19 Comment(2)
There are use cases other than sensitive data in which you may not want to serialize a field. For example, you probably would never want to serialize a Thread (credit to @Infold for example), in which case you would mark it as transient. However, a thread is not sensitive data in and of itself, it just makes no logical sense to serialize it (and it is not serializable).Zeidman
@Zeidman That case isn't excluded by this answer. It certainly is needed as things stand in the case the poster mentioned.Calaboose
F
5

As per google transient meaning == lasting only for a short time; impermanent.

Now if you want to make anything transient in java use transient keyword.

Q: where to use transient?

A: Generally in java we can save data to files by acquiring them in variables and writing those variables to files, this process is known as Serialization. Now if we want to avoid variable data to be written to file, we would make that variable as transient.

transient int result=10;

Note: transient variables cannot be local.

Falco answered 2/11, 2014 at 8:56 Comment(0)
D
2

Because not all variables are of a serializable nature.

  1. Serialization and Deserialization are symmetry processes, if not, then 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. For example, you can't serialize a Stream object.

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

Debunk answered 4/7, 2020 at 3:28 Comment(0)
H
1

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);
    }
}
Hypercritical answered 5/6, 2019 at 3:9 Comment(0)
K
0

Simply put, the transient java keyword protect fields from the been Serialize as their non-transient fields counter parts.

In this code snippet our abstract class BaseJob implement Serializable interface, we extends from BaseJob but we need not serialize the remote and local data sources; serialize only organizationName and isSynced fields.

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;

   }
}
Kattiekatuscha answered 14/11, 2017 at 13:40 Comment(0)
H
0

A field which is declare with transient modifier it will not take part in serialized process. When an object is serialized(saved in any state), the values of its transient fields are ignored in the serial representation, while the field other than transient fields will take part in serialization process. That is the main purpose of the transient keyword.

Holoblastic answered 24/1, 2020 at 9:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.