Provide Best Programming Tutorials

String In Java

Strings

Strings, which are widely used in Java programming, are a sequence of characters. In the Java programming language, strings are objects.

The Java platform provides the String class to create and manipulate strings.

Constructors Of java.lang.String Class

There are 13 constructors for String. You can check out the detail here.
Below are the most frequently used constructors:
If you want to create an empty string object, then use no-arg constructor of String class.

String s = new String();     //It creates a string object without characters in it.

below constructor construct string from the char array.

char[] chars = {'J', 'A', 'V', 'A'};     //Character Array
String s = new String(chars);    //Creating a String object by passing character array as an argument

receive String as a parameter:

String s = new String("JAVA");   //Creating a string object by passing string as an argument

construct from StringBuilder

StringBuffer strBuff = new StringBuffer("abc");
String s = new String(strBuff);   //Creating a string object by passing StringBuffer type as an argument

construct from StringBuffer

StringBuilder strBldr = new StringBuilder("abc");
String s = new String(strBldr);   //Creating a string object by passing StringBuilder type as an argument.

String Literals

In Java, all string literals like “java”, “abc”, “123” are treated as objects of java.lang.String class. That means all methods of String class are also applicable to string literals.
You can also create the objects of String class without using the new operator. This can be done by assigning a string literal to the reference variable of type java.lang.String class.

public class StringExamples{
    public static void main(String[] args){
        //Creating String objects without using new operator
 
        String s1 = "abc";          
 
        String s2 = "abc"+"def";
 
        String s3 = "123"+"A"+"B";
 
        System.out.println(s1);     //Output : abc
 
        System.out.println(s2);     //Output : abcdef
 
        System.out.println(s3);     //Output : 123AB
    }
}

How The Strings Are Stored In The Memory

In Java, strings are special. Java gives some special attention to string types that no other types enjoy such attention. For example, to create the string objects you need not use ‘new‘ keyword. Whereas to create another type of objects you have to use ‘new’ keyword. Like this, strings enjoy some special attention by the java. This attention is worth the while because the strings are used almost everywhere while developing any kind of applications.

While storing the string objects in the memory also, they are specially treated by the Java. After reading this article, you will come to know how they are specially treated in memory.

We all know that JVM divides the allocated memory to a Java program into two parts. one is Stack and another one is the heap. The stack is used for execution purpose and heap is used for storage purpose. In that heap memory, JVM allocates some memory specially meant for string literals. This part of the heap memory is called String Constant Pool.

Whenever you create a string object using the string literal, that object is stored in the string constant pool and whenever you create a string object using the new keyword, such object is stored in the heap memory.

For example, when you create string objects like below, they will be stored in the String Constant Pool.

String s1 = "abc"; 
 
String s2 = "xyz";
 
String s3 = "123";
 
String s4 = "A";

And when you create string objects using the new keyword like below, they will be stored in the heap memory.

String s5 = new String("abc");
 
char[] c = {'J', 'A', 'V', 'A'};
 
String s6 = new String(c);
 
String s7 = new String(new StringBuffer());

This is how String Constant Pool looks like in the memory.

One more interesting thing about String Constant Pool is that pool space is allocated to an object depending upon it’s content. There will be no two objects in the pool having the same content.

This is what happens when you create string objects using the string literal,

“When you create a string object using the string literal, JVM first checks the content of to be created object. If there exists an object in the pool with the same content, then it returns the reference of that object. It doesn’t create a new object. If the content is different from the existing objects then only it creates a new object.”

But, when you create string objects using the new keyword, a new object is created whether the content is the same or not.

This can be proved by using “==” operator. As “==” operator returns true if two objects have the same physical address in the memory otherwise it will return false. In the below example, s1 and s2 are created using string literal “abc”. So, s1 == s2 returns true. Whereas s3 and s4 are created using new operator having the same content. But, s3 == s4 returns false.

public class StringExamples{
    public static void main(String[] args){
        //Creating string objects using literals
 
        String s1 = "abc";
 
        String s2 = "abc";
 
        System.out.println(s1 == s2);        //Output : true
 
        //Creating string objects using new operator
 
        String s3 = new String("abc");
 
        String s4 = new String("abc");
 
        System.out.println(s3 == s4);        //Output : false
    }
}

In simple words, there can not be two string objects with the same content in the string constant pool. But, there can be two string objects with the same content in the heap memory.

What Is String Intern In Java

String objects in Java are stored in two places in memory. One is String Constant Pool and another one is Heap Memory. String objects created using string literals are stored in String Constant Pool whereas string objects created using new operator are stored in heap memory.

Why You Need String Constant Pool

String objects are the most used objects in the development of any kind of applications. Therefore, there has to be a special arrangement to store these objects. String Constant Pool is one such special arrangement. In string constant pool, there will be no two objects with the same content. Heap memory can have any number of objects with the same content.

Just imagine creating 1000 string objects with the same content in heap memory and one string object with that content in String Constant Pool. Which one saves the memory?. which one will save time?. Which one will be accessed faster?. It is, of course, String Constant Pool. That’s why you need String Constant Pool.

What Is String Intern

String intern or simply intern refers to a string object in the String Constant Pool. Interning is the process of creating a string object in String Constant Pool which will be an exact copy of string object in heap memory.

READ :  Introduction To Strings

intern() Method

intern() method of java.lang.String class is used to perform interning i.e creating an exact copy of heap string object in string constant pool. When you call this method on a string object, first it checks whether there exists an object with the same content in the String Constant Pool. If the object does not exist in the pool, it will create an object with the same content in the string constant pool and returns the reference of that object. If the object exists in the pool than it returns the reference of that object without creating a new object.

Look at the below example. Object ‘s1’ will be created in heap memory as we are using a new operator to create it. When we call intern() method on s1, it creates a new string object in the string constant pool with “JAVA” as it’s content and assigns it’s reference to s2. So, s1 == s2 will return false because they are two different objects in the memory and s1.equals(s2) will return true because they have the same content.

public class StringExamples{
    public static void main(String[] args){
        String s1 = new String("JAVA");

        String s2 = s1.intern();       //Creating String Intern

        System.out.println(s1 == s2);       //Output : false

        System.out.println(s1.equals(s2));    //Output : true
    }
}

Look at this example. Object s1 will be created in string constant pool as we are using the string literal to create it and object s2 will be created in heap memory as we are using a new operator to create it. When you call intern() method on s2, it returns the reference of the object to which s1 is pointing as it’s content is same as s2. It does not create a new object in the pool. So, S1 == s3 will return true as both are pointing to the same object in the pool.

public class StringExamples{
    public static void main(String[] args){
        String s1 = "JAVA";
 
        String s2 = new String("JAVA");
 
        String s3 = s2.intern();       //Creating String Intern
 
        System.out.println(s1 == s3);       //Output : true
    }
}

String Literals Are Automatically Interned

When you call intern() on the string object created using string literals it returns the reference of itself. Because you can’t have two string objects in the pool with the same content. That means string literals are automatically interned in java.
public class StringExamples{
    public static void main(String[] args){
        String s1 = "JAVA";
 
        String s2 = s1.intern();       //Creating String Intern
 
        System.out.println(s1 == s2);       //Output : true
    }
}

What is the use of interning the string

To Save The memory Space 

READ: An Example To Prove Strings Are Immutable

Using interned string, you can save the memory space. If you are using lots of string objects with the same content in your code than it is better to create an intern of that string in the pool. Use that intern string whenever you need it instead of creating a new object in the heap. It saves the memory space.

For Faster Comparison 

Assume that there are two string objects s1 and s2 in heap memory and you need to perform the comparison of these two objects more often in your code. Then using s1.intern() == s2.intern() will be more fast then s1.equals(s2). Because equals() method performs character by character comparison whereas “==” operator just compares references of objects.

Why String is immutable in Java?

String is immutable in Java. An immutable class is simply a class whose instances cannot be modified. All information in an instance is initialized when the instance is created and the information cannot be modified. There are many advantages of immutable classes. This article summarizes why is String designed to be immutable. This post illustrates the immutability concept from the perspective of memory, synchronization and data structures.

1. The requirement of String Pool

String pool (String intern pool) is a special storage area in the Method Area. When a string is created and if the string already exists in the pool, the reference of the existing string will be returned, instead of creating a new object.

The following code will create only one string object in the heap.

String string1 = "abcd";
String string2 = "abcd";

Here is how it looks:
java-string-pool

 

 

 

 

 

 

If a string is mutable, changing the string with one reference will lead to the wrong value for the other references.

2. Caching Hashcode

The hash code of a string is frequently used in Java. For example, in a HashMap or HashSet. Being immutable guarantees that hashcode will always be the same so that it can be cashed without worrying about the changes. That means, there is no need to calculate hashcode every time it is used. This is more efficient.

In String class, it has the following code:

private int hash;//this is used to cache hash code.

3. Facilitating the Use of Other Objects

To make this concrete, consider the following program:

HashSet<String> set = new HashSet<String>();
set.add(new String("a"));
set.add(new String("b"));
set.add(new String("c"));
 
for(String a: set)
  a.value = "a";

In this example, if String is mutable, its value can be changed which would violate the design of set (set contains unduplicated elements). Of curse, the example above is just for demonstration purpose and there is no field value in a real string class.

4. Security

The string is widely used as a parameter for many java classes, e.g. network connection, opening files, etc. Were String not immutable, a connection or file would be changed and this can lead to a serious security threat. The method thought it was connecting to one machine, but was not. Mutable strings could cause a security problem in Reflection too, as the parameters are strings.

Here is a code example:

boolean connect(string s){
    if (!isSecure(s)) { 
throw new SecurityException(); 
}
    //here will cause problem, if s is changed before this by using other references.    
    causeProblem(s);
}

5. Immutable objects are naturally thread-safe

Because immutable objects can not be changed, they can be shared among multiple threads freely. This eliminates the requirements of doing synchronization.

In summary, String is designed to be immutable for efficiency and security reasons. This is also the reason why immutable classes are preferred in many cases in general.

StringBuffer & StringBuilder

Since String is immutable in Java this means once you create a String you cannot change it. But there are always the cases you wanna modify a String, for example, you may use “+” to compact two Strings or you may wanna get the uppercase of the given String etc, these operations generate a new String and discard the older String for garbage collection.

These are heavy operations and generate a lot of garbage in heap. So Java has provided StringBuffer and StringBuilder class that should be used for String manipulation.

StringBuilder and StringBuffer are mutable objects provide some useful methods for manipulating String. The String is not turned into “concrete product” until we call a certain method of StringBuilder & StringBuffer. This brings the flexibility of manipulating the String Object.

StringBuilder vs StringBuffer

StringBuffer was the only choice for String manipulation till Java 1.4 but it has one disadvantage that all of its public methods are synchronized. StringBuffer provides Thread safety but on a performance cost.

In most of the scenarios, we don’t use String in a multithreaded environment, so Java 1.5 introduced a new class StringBuilder that is similar with StringBuffer except thread safety and synchronization.

So if you are in a single threaded environment or don’t care about thread safety, you should use StringBuilder else use StringBuffer.

We will only talk about StringBuilder later since the only difference between StringBuilder & StringBuffer is that StringBuffer is used for multithread environment.

StringBuilder

StringBuilder objects are like String objects, except that they can be modified. Internally, these objects are treated like variable-length arrays that contain a sequence of characters. At any point, the length and content of the sequence can be changed through method invocations.

Strings should always be used unless string builders offer an advantage in terms of simpler code (see the sample program at the end of this section) or better performance. For example, if you need to concatenate a large number of strings, appending to a StringBuilder object is more efficient.

The StringBuilder class has some methods related to length and capacity that the String class does not have:

Length and Capacity Methods
Method Description
void setLength(int newLength) Sets the length of the character sequence. If newLength is less than length(), the last characters in the character sequence are truncated. If newLength is greater than length(), null characters are added at the end of the character sequence.
void ensureCapacity(int minCapacity) Ensures that the capacity is at least equal to the specified minimum.

A number of operations (for example, append()insert(), or setLength()) can increase the length of the character sequence in the string builder so that the resultant length() would be greater than the current capacity(). When this happens, the capacity is automatically increased.

StringBuilder Example

package stringdemo;

public class StringBuilderDemo {
    public static void main(String[] args) {
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("Andrew ");
        stringBuilder.append("Programming");

        String result = stringBuilder.toString();
        System.out.println("Result:" + result);


        String rs = stringBuilder.reverse().toString();
        System.out.println("Reverse Result:" + rs);

        stringBuilder.reverse();
        String insertResult = stringBuilder.insert(stringBuilder.length(), " Is Great!").toString();
        System.out.println("Insert Result:" + insertResult);


    }
}

output

Result:Andrew Programming
Reverse Result:gnimmargorP werdnA
Insert Result:Andrew Programming Is Great!

Notice until we call toString() method we really generate a String. So the programming above just create 3 Strings since we call toString() method 3 times.

 

Leave a Reply

Close Menu