Why String is final in Java ? or why String is Immutable?


The above two Questions are related  as  Immutable --> final

consider the below scenario If String is not a Final Class

i had a String Object  String super="Java";

i have two subclasses of String  super( parent Class)  Class A and Class B.if Class A changes  its reference to A="J2EE" then the reference of Class B also points to J2EE.which is not a thread safe.

Some of the reasons why it made as Immutable :
  • The designers wanted to guarantee that the invariants of String could not be changed by a sub-class. To guarantee that String itself would not change they implemented parent delegation in class loaders 
  • Another reason of Why String is immutable in Java is to allow String to cache its hashcode , being immutable String in Java caches its hashcode and do not calculate every time we call hashcode method of String, which makes it very fast as hashmap key to be used in hashmap in Java.  
  • The absolutely most important reason that String is immutable is that it is used by the class loading mechanism, and thus have profound and fundamental security aspects.As in JVM  String is mostly used parameter for loading classes or opening the connections.
  • and one more reason is for thread safety.

so the Question is how we can design a Immutable class
  • Declare all fields Private Final.
  • Set all fields in the constructor.
  • Don't provide any methods that modify the state of the object; provide only getter methods (no setters).
  • Declare the class final, so that no methods may be overridden.
  • Ensure exclusive access to any mutable components, e.g. by returning copies.
Example :
import java.util.Date;

/**
* Planet is an immutable class, since there is no way to change
* its state after construction.
*/
public final class Planet {

  public Planet (double aMass, String aName, Date aDateOfDiscovery) {
     fMass = aMass;
     fName = aName;
     //make a private copy of aDateOfDiscovery
     //this is the only way to keep the fDateOfDiscovery
     //field private, and shields this class from any changes that 
     //the caller may make to the original aDateOfDiscovery object
     fDateOfDiscovery = new Date(aDateOfDiscovery.getTime());
  }

  /**
  * Returns a primitive value.
  *
  * The caller can do whatever they want with the return value, without 
  * affecting the internals of this class. Why? Because this is a primitive 
  * value. The caller sees its "own" double that simply has the
  * same value as fMass.
  */
  public double getMass() {
    return fMass;
  }

  /**
  * Returns an immutable object.
  *
  * The caller gets a direct reference to the internal field. But this is not 
  * dangerous, since String is immutable and cannot be changed.
  */
  public String getName() {
    return fName;
  }

//  /**
//  * Returns a mutable object - likely bad style.
//  *
//  * The caller gets a direct reference to the internal field. This is usually dangerous, 
//  * since the Date object state can be changed both by this class and its caller.
//  * That is, this class is no longer in complete control of fDate.
//  */
//  public Date getDateOfDiscovery() {
//    return fDateOfDiscovery;
//  }

  /**
  * Returns a mutable object - good style.
  * 
  * Returns a defensive copy of the field.
  * The caller of this method can do anything they want with the
  * returned Date object, without affecting the internals of this
  * class in any way. Why? Because they do not have a reference to 
  * fDate. Rather, they are playing with a second Date that initially has the 
  * same data as fDate.
  */
  public Date getDateOfDiscovery() {
    return new Date(fDateOfDiscovery.getTime());
  }

  // PRIVATE //

  /**
  * Final primitive data is always immutable.
  */
  private final double fMass;

  /**
  * An immutable object field. (String objects never change state.)
  */
  private final String fName;

  /**
  * A mutable object field. In this case, the state of this mutable field
  * is to be changed only by this class. (In other cases, it makes perfect
  * sense to allow the state of a field to be changed outside the native
  * class; this is the case when a field acts as a "pointer" to an object
  * created elsewhere.)
  */
  private final Date fDateOfDiscovery;
}
 
References :

  • http://www.javapractices.com/topic/TopicAction.do?Id=29
  • http://renaud.waldura.com/doc/java/final-keyword.shtml
  • http://stackoverflow.com/questions/2068804/why-is-string-final-in-java

1 comment:

  1. Thanks....please go through this blog http://adnjavainterview.blogspot.in/2014/06/why-string-is-immutable-or-final-in-java.html also explained nice..

    ReplyDelete