Transient methods in java

Java transient keyword example

The Java transient keyword is used on class attributes/variables to indicate that serialization process of such class should ignore such variables while creating a persistent byte stream for any instance of that class.

A transient variable is a variable that can not be serialized. According to Java Language Specification [jls-8.3.1.3] – “Variables may be marked transient to indicate that they are not part of the persistent state of an object.”

In this post, I will discussing various concepts involved around usage of transient keyword in context of serialization.

Table of Contents 1. What is transient keyword in Java? 2. When should we use transient keyword in java? 3. Usage of transient with final keyword 4. Case study: How does a HashMap use transient? 5. Summary Notes 

1. What is Java transient keyword

The modifier transient in java can be applied to field members of a class to turn off serialization on these field members. Every field marked as transient will not be serialized. You use the transient keyword to indicate to the java virtual machine that the transient variable is not part of the persistent state of an object.

Let’s write an very basic example to understand what exactly above analogy means. I will create an Employee class and will define 3 attributes i.e. firstName, lastName and confidentialInfo. We do not want to store/save “confidentialInfo” for some purpose so we will mark the field as “transient“.

class Employee implements Serializable < private String firstName; private String lastName; private transient String confidentialInfo; //Setters and Getters >

Now let’s serialize an instance of Employee class.

Now let’s de-serialize back into java object, and verify if “confidentialInfo” was saved or not?

Clearly, “confidentialInfo” was not saved to persistent state while serialization and that’s exactly why we use “transient” keyword in java.

2. When should we use transient keyword in java?

Now we have a very knowledge of “transient” keyword. Let’s expand out understanding by identifying the situations where you will need the use of transient keyword.

  1. First and very logical case would be where you may have fields that are derived/calculated from other fields within instance of class. They should be calculated programmatically everytime rather than having the state be persisted via serialization. An example could be time-stamp based value; such as age of a person OR duration between a timestamp and current timestamp. In both cases, you would be calculating value of variable based on current system time rather than when the instance was serialized.
  2. Second logical example can be any secure information which should not leak outside the JVM in any form (either in database OR byte stream).
  3. Another example could be fields which are not marked as “Serializable” inside JDK or application code. Classes which do not implement Serializable interface and are referenced within any serializable class, cannot be serialized; and will throw “java.io.NotSerializableException” exception. These non-serializable references should be marked “transient” before serializing the main class.
  4. And lastly, there are times when it simply doesn’t make sense to serialize some fields. Period. For example, In any class if you have added a logger reference, then what’s use of serializing that logger instance. Absolutely no use. You serialize the information which represent the state of instance, logically. Loggers never share the state of an instance. They are just utilities for programming/debugging purpose. Similar example can be reference of a Thread class. Threads represent a state of a process at any given point of time, and there is no use to store thread state with your instance; simply because they do not constitute the state of your class’s instance.
Читайте также:  Check permission android kotlin

Above four usecases are when you should use the keyword “transient” with reference variables. If you have some more logical cases where “transient” can be used; please share with me and I will update that here in list so that everybody can benefit from your knowledge.

I am talking about use of transient with final keyword specifically because it behaves differently in different situations which is not generally the case with other keywords in java.

For making this concept practical, I have modified the Employee class as below:

private String firstName; private String lastName; //final field 1 public final transient String confidentialInfo = "password"; //final field 2 public final transient Logger logger = Logger.getLogger("demo");

Now when I again run the serialization (write/read) again, below is the output:

Lokesh Gupta password null

This is strange. We have marked the “confidentialInfo” to transient; and still the field was serialized. For similar declaration, logger was not serialized. Why?

Reason is that whenever any final field/reference is evaluated as “constant expression“, it is serialized by JVM ignoring the presence of transient keyword.

In above example, value “ password ” is a constant expression and instance of logger “ demo ” is reference. So by rule, confidentialInfo was persisted where as logger was not.

Are you thinking, what if I remove “ transient ” from both fields? Well, then fields implementing Serializable references will persist otherwise not. So, if you remove transient in above code, String (which implements Serializable) will be persisted; where as Logger (which does NOT implements Serializable) will not be persisted AND “java.io.NotSerializableException” will be thrown.

If you want to persist the state of non-serializable fields then use readObject() and writeObject() methods. writeObject()/readObject() are usually chained into serialization/deserialization mechanisms internally and thus called automatically.

4. Case study : How does a HashMap use transient keyword?

So far, we have been talking about concepts related to “transient” keyword which are mostly theoretical in nature. Let’s understand the proper use of “transient” which is used inside HashMap class very logically. It will give you better idea about real life usage of transient keyword in java.

Читайте также:  Php генерация уникальной строки

Before understanding the solution which has been created using transient, let’s first identify the problem itself.

HashMap is used to store key-value pairs, we all know that. And we also know that location of keys inside HashMap is calculated based on hash code obtained for instance of key. Now when we serialize a HashMap that means all keys inside HashMap and all values respective to key’s will also be serialized. After serialization, when we de-serialize the HashMap instance then all key instances will also be deserialized. We know that during this serialization/deserialization process, there may be loss of information (used to calculate hashcode) as well as most important is it is a NEW INSTANCE itself.

In java, any two instances (even of same class) can not have same hashcode. This is a big problem because the location where keys should be placed according to new hashcodes, are not in there correct positions. When retrieving the value of a key, you will be referring to the wrong index in this new HashMap.

So, when a hash map is serialized, it means that the hash index, and hence the ordering of the table is no longer valid and should not be preserved. This is the problem statement.

Now look at how it is solved inside HashMap class. If go through the sourcecode of HashMap.java, you will find below declarations:

transient Entry table[]; transient int size; transient int modCount; transient int hashSeed; private transient Set entrySet;

All important fields have been marked at “transient” (all of them are actually calculated/change at runtime), so they are not part of serialized HashMap instance. To populate again this important information back, HashMap class uses writeObject() and readObject() methods as below:

private void writeObject(ObjectOutputStream objectoutputstream) throws IOException < objectoutputstream.defaultWriteObject(); if (table == EMPTY_TABLE) objectoutputstream.writeInt(roundUpToPowerOf2(threshold)); else objectoutputstream.writeInt(table.length); objectoutputstream.writeInt(size); if (size >0) < Map.Entry entry; for (Iterator iterator = entrySet0().iterator(); iterator.hasNext(); objectoutputstream.writeObject(entry.getValue())) < entry = (Map.Entry) iterator.next(); objectoutputstream.writeObject(entry.getKey()); >> > private void readObject(ObjectInputStream objectinputstream) throws IOException, ClassNotFoundException < objectinputstream.defaultReadObject(); if (loadFactor 0) inflateTable(j); else threshold = j; init(); for (int k = 0; k < i; k++) < Object obj = objectinputstream.readObject(); Object obj1 = objectinputstream.readObject(); putForCreate(obj, obj1); >>

With above code, HashMap still let the non-transient fields to be treated as they would normally do, but they wrote the stored key-value pairs at the end of the byte array one after the other. While de-serializing, it let the non-transient variables to be handled by default de-serialization process and then read the key-value pairs one by one. For each key the hash and the index is calculated again and is inserted to the correct position in the table so that it can be retrieved again without any error.

Читайте также:  Изображение

Above use of transient keyword was a very good example of proper usecase. You should keep remember it and mention it whenever it is asked in your next java interview question.

  1. The modifier transient can be applied to field members of a class to turn off serialization on these field members.
  2. You can use transient keyword in classes with fields which needs to be secured or calculated on existing state fields. And use it when it simply doesn’t make sense to serialize those fields such as loggers and threads.
  3. Serialization does not care about access modifiers such as private; all non-transient fields are considered part of an object’s persistent state and are eligible for persistence.
  4. Whenever any final field/reference is evaluated as “constant expression”, it is serialized by JVM ignoring the presence of transient keyword.
  5. A good usecase of transient keyword in java is HashMap class.

That’s all from my side for “transient” keyword. If you want to add something in this post, please do let me know via comments. I will be happy to expand this post.

If you want to learn more concepts like this in future, I will suggest you to join my mailing list/ OR follow me on Google Plus/Facebook or Twitter. I do post interesting links other than howtodoinjava.com in my social profiles.

Источник

Transient methods in java

Provides the Java 2D classes for defining and performing operations on objects related to two-dimensional geometry.

Provides a set of «lightweight» (all-Java language) components that, to the maximum degree possible, work the same on all platforms.

Uses of Transient in java.awt

Returns the current x,y position within the child which is displayed at the 0,0 location of the scrolled panel’s view port.

Uses of Transient in java.awt.geom

Methods in java.awt.geom with annotations of type Transient
Modifier and Type Method and Description
Rectangle2D RectangularShape. getFrame ()

Uses of Transient in java.awt.im

Methods in java.awt.im with annotations of type Transient
Modifier and Type Method and Description
boolean InputContext. isCompositionEnabled ()

Uses of Transient in javax.swing

Methods in javax.swing with annotations of type Transient
Modifier and Type Method and Description
int DefaultListSelectionModel. getAnchorSelectionIndex ()

Return the first index argument from the most recent call to setSelectionInterval(), addSelectionInterval() or removeSelectionInterval().

Return the second index argument from the most recent call to setSelectionInterval(), addSelectionInterval() or removeSelectionInterval().

Uses of Transient in javax.swing.table

Uses of Transient in javax.swing.text

Uses of Transient in javax.swing.tree

Methods in javax.swing.tree with annotations of type Transient
Modifier and Type Method and Description
void DefaultMutableTreeNode. setParent (MutableTreeNode newParent)

Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2023, Oracle and/or its affiliates. All rights reserved. Use is subject to license terms. Also see the documentation redistribution policy.

Источник

Оцените статью