Why Does Java Have Transient Fields

Why does Java have transient fields?

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.

What does the keyword transient mean in Java?

Google is your friend - first hit - also you might first have a look at what serialization is.

It marks a member variable not to be
serialized when it is persisted to
streams of bytes. When an object is
transferred through the network, the
object needs to be 'serialized'.
Serialization converts the object
state to serial bytes. Those bytes are
sent over the network and the object
is recreated from those bytes. Member
variables marked by the java transient
keyword are not transferred, they are
lost intentionally.

Example from there, slightly modified (thanks @pgras):

public class Foo implements Serializable
{
private String saveMe;
private transient String dontSaveMe;
private transient String password;
//...
}

Why use the `transient` keyword in java?

transient variables are never serialized in java.

It marks a member variable not to be serialized when it is persisted to streams of bytes. When an object is transferred through the network, the object needs to be 'serialized'. Serialization converts the object state to serial bytes. Those bytes are sent over the network and the object is recreated from those bytes. Member variables marked by the java transient keyword are not transferred, they are lost intentionally.

please have a look at what serialization is.? and also refer this

Example

public class Foo implements Serializable
{
private String saveMe;
private transient String dontSaveMe;
private transient String password;
//...
}

In above example dontSaveMe & password are never get serialize as they are declare as a transient variables.

Why does JPA have a @Transient annotation?

Java's transient keyword is used to denote that a field is not to be serialized, whereas JPA's @Transient annotation is used to indicate that a field is not to be persisted in the database, i.e. their semantics are different.

What is the use of transient variables?

Some classes are inherently not serializable, because they represent resources outside of the manage Java environment. For example a FileOutputStream can't really be serialized, because it represents an open file handle. The same is true for a Socket: you can't save and restore "open sockets".

If you want to serialize some object that has a field of that type, then you'll have to mark those fields as transient.

Another reason to use transient is when your class does some kind of internal caching. If, for example, your class can do calculations and for performance reasons it caches the result of each calculation, then saving that cache might not be desirable (because recalculating it might be faster than restoring it, or because it's unlikely that old cached values are of any use). In this case you'd mark the caching fields as transient.

Why doesn't XMLDecoder respect the transient keyword?

XML encoders/decoders favor the @XMLTransient annotation.

The transient keyword is for the java object serialization process which ends up in byte sequences. XML "serialization" ends up in a formatted text document. There might be different aspects when you choose a field not to serialize (by marking it transient) and since the output is quite different, you might wanna choose different fields that you want to exclude and handle them yourself. For example in case of Java serialization you might want to choose to serialize a byte[] because it is easy and straightforward. In case of XML you might want to serialize the object that was used to create that byte array if it has a nicer/more meaningful text representation.

@XMLTransient is used by JAXB. For XMLEncoder to exclude a field (mark it transient), you have to set a "transient" property to TRUE in their PropertyDescriptor: (source)

BeanInfo info = Introspector.getBeanInfo(JTextField.class);
PropertyDescriptor[] propertyDescriptors =
info.getPropertyDescriptors();
for (int i = 0; i < propertyDescriptors.length; ++i) {
PropertyDescriptor pd = propertyDescriptors[i];
if (pd.getName().equals("text")) {
pd.setValue("transient", Boolean.TRUE);
}
}

It's not an elegant solution. An alternative is to use JAXB instead of XMLEncoder.

Can a transient field in a class be obtained using reflection

Yes, It is a normal field. You can check whether it is transient by:

Modifier.isTransient(field.getModifiers());

transient:
A keyword in the Java programming language that indicates that a field is not part of the serialized form of an object. When an object is serialized, the values of its transient fields are not included in the serial representation, while the values of its non-transient fields are included.

So no logical reason for it not to be accessible by reflection. It's the value of the field that is ignored (sometimes), not the field itself.

(btw, what hindered you from just trying to call getDeclaredField("yourTransientField")?)

Because of Hibernate Mapping need to have some of the fields as @Transient but JSP does not have access to them

Try renaming the methods to match the JavaBean specification.

Instead of:

@Transient
public String getid() {
return tta.getMyIds().getId();
}

public void setid(String id) {
this.tta.getMyIds().setId(id);
}

you should have:

@Transient
public String getId() {
return tta.getMyIds().getId();
}

public void setId(String id) {
this.tta.getMyIds().setId(id);
}

Serialization/Deserialization of the final transient fields

During deserialization, the constructor of the object is not called. This is a special object instantiation process handled by the JVM.

For aVar2 and aVar4, the Hashmap and string constructor is called. So these variables are assigned default values(null).

For aVar1 and aVar3, some constant expression is assigned to them. These are called compile time constants.

The conditions for compile time constants are

  1. They must be declared final
  2. They are of primitive data types or String
  3. They must be initialized with their declaration.
  4. Their value must be constant expression.

Compile time constants are reaffected and these values will be retained after deserialisation.



Related Topics



Leave a reply



Submit