This is one of the favourite questions at the fresher level that interviewer asks. Most of the candidates tend to gloss over this. If interviewer tends to go into this deep, most of the candidates tend to falter. At least that if what I have observed having interviewed hundreds of candidates in the past.
We will try and make this article single point of reference for Strings in Java. Hopefully we cover something that might be helpful to you. Read here, for knowing Why It was made Immutable.
Let's try and go in depth on String immutability.
Let's start by Source Code of String.java. I always say that source code is the best resource to learn a language.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public final class String | |
implements java.io.Serializable, Comparable<String>, CharSequence { | |
/** The value is used for character storage. */ | |
private final char value[]; | |
/** The offset is the first index of the storage that is used. */ | |
private final int offset; | |
/** The count is the number of characters in the String. */ | |
private final int count; | |
/** Cache the hash code for the string */ | |
private int hash; // Default to 0 | |
/** use serialVersionUID from JDK 1.0.2 for interoperability */ | |
private static final long serialVersionUID = -6849794470754667710L; | |
... | |
} |
How String is Immutable?
This question is self answered by the above code snippet. Member variable data type is final. Hence String Object once created becomes immutable in Java.
How come then we are able to assign same variable, a different value?
Now we are talking. Valid question. Let's check it via code,
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImmutableString{ | |
public static void main(String args[]) { | |
String immutable = "javaonjava"; | |
System.out.println("First String " + immutable); | |
immutable = "stringchanged"; | |
System.out.println("Changed String " + immutable); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
First String javaonjava | |
Changed String stringchanged |
So the question stands. What does immutability means?
Well, it can be explained by what happens internally. Variable immutable refers to a memory space which is allocated to "javaonjava. This memory allocation is what we call immutable. Same variable can point to different memory spaces.
String literals are stored separately in a String Pool. Once a String is Created, say "javaonjava". Whenever a new variable needs "javaonjava" String, a new String is not created. The old one is referenced. This is what we mean by immutability. So String Object is not immutable, String itself is immutable.
Compare it with any User defined object. When that object is updated, content is re-written on the same memory space. Hope things are getting clear now.
How to check String is immutable in Java
1. == (equals operator), is the best check.
As we read above StringPool contains single copy of a given String. So if this operator returns true on two string variables, it means they are pointing to same memory and content inside the StringPool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class StringEquality{ | |
public static void main(String args[]) { | |
String first = "javaonjava"; | |
String second = "javaonjava"; | |
System.out.println("first equals second "+ (first == second)); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
first equals second true |
Thus we see, they both point to the same content.
2. No operations modify String
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImmutableString{ | |
public static void main(String args[]) { | |
String immutable = "javaonjava"; | |
immutable.substring(2,5); | |
System.out.println(immutable); | |
immutable.concat("somemore"); | |
System.out.println(immutable); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
javaonjava | |
javaonjava |
Thus we see neither concat, nor substring modifies the String. They simply create a new String, which is returned as we see below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ImmutableString{ | |
public static void main(String args[]) { | |
String immutable = "javaonjava"; | |
immutable = immutable.substring(2,5); | |
System.out.println(immutable); | |
immutable = immutable.concat("somemore"); | |
System.out.println(immutable); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
vao | |
vaosomemore |
In the last example, what happens to "javaonjava" String. Well it remains in the StringPool but unreferenced. If not reused for considerable time, it could be Garbage Collected.
See the diagram below for better understanding
No comments:
Post a Comment