Java 11 Developer Certification - String Basics

October 01, 2020

What we are covering in this lesson

  1. What is String
  2. Types of String
  3. Why are Strings immutable in Java
  4. Different ways of String creation

What is String

A String in java is an object of class java.lang.String. It represents a series or array of characters BUT it is not an array of primitive data type char.

Types of String

String creation can be done in two ways

  • Using the String class, a.k.a. String Object String newString = new String();
  • Without the new operator, a.k.a String literal String literalString = "Literal String";

There is a special area in heap memory called the String Pool. All the String literals are stored in this area. Purpose of String Pool is to maintain a set of unique String, and this process is called Interning.

We can also manually intern using the intern method on a String object.

Two variables assigned to the same String literal are considered equal and the comparator ”==” evaluates to true.

package maxCode.online.String;

public class StringClass {
	public static void main(String[] args) {
		String s1 = "Literal";
		String s2 = "Literal";
		
		System.out.println("Output of == is " + (s1 == s2));    
		System.out.println("Output of equals is " + s1.equals(s2));
	}
}

The output is

Output of == is true
Output of equals is true

Now, lets try the same with a String Object

package maxCode.online.String;

public class StringObject {
	 public static void main(String[] args) {
		String s1 = new String("ObjectTest");
		String s2 = new String("ObjectTest");
		
		System.out.println("Output of == is " + (s1 == s2));
		System.out.println("Output of equals is " + s1.equals(s2));
	}
}

The output is

Output of == is false
Output of equals is true

This means when we assign the string to a pool, the reference for same strings remains the same. On the other hand when we create objects of String using new, the object value might be same but the objects created are different.

We can use the intern method to push the String object to String pool.

package maxCode.online.String;

public class StringIntern {
	public static void main(String[] args) {
		String s1 = new String("ObjectTest").intern();
		String s2 = new String("ObjectTest").intern();
		
		System.out.println("Output of == is " + (s1 == s2));
		System.out.println("Output of equals is " + s1.equals(s2));
	}
}

The output is

Output of == is true
Output of equals is true

Why are Strings immutable in Java

Strings in Java are immutable, meaning they cannot be changed once created. So if you create a string literal “Literal”, the string will remain in the pool with a single reference. String concatenation only creates a new literal, and the variable reference is changed to this new literal. Lets see more using an example.

package maxCode.online.String;

public class ImmutableString {
	public static void main(String[] args) {
		String s1 = "String";
		s1 = s1 + " Literal";
		System.out.println(s1);
		
		s1 = "String";
		s1.concat(" Literal");
		System.out.println(s1);
	}
}

Output:

String Literal
String

Lets understand the code. It starts with putting “String” to the pool and returning a reference to s1. Next line will create another literal “String Literal” and return its reference to s1. Note that the first reference still remains in the pool, and the newly created “String Literal” does not exist in the pool until explicitly intern is called. Next, we reset s1 to “String” and do a concatenation. Now the concatenation does the same thing as we did previously with ”+”, just that the reference to the new literal is not stored back to s1, and hence the output is String only. The string concat method will return a pointer to the concatenated string, which is itself a new immutable string, but the code above didn’t assign the result of a concat method to any variable.

So, if we do a s1 = s1.concat(" Literal");, the output would change to String Literal.

Different ways of String creation

There are multiple ways in which we can create String, as mentioned below.

  • A String literal, e.g. String literal = "Literal";
  • String constructors

    • Without parameter String s1 = new String();
    • With single String parameter String s2 = new String("Constructor");
    • String concatenation String s3 = "abcd" + " efgh";
    • Multiple parameters in case of byte array or char array as first parameter

Lets look at the possible ways using java code

package maxCode.online.String;

import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

public class StringOptions {
	public static void main(String[] args) throws UnsupportedEncodingException {
		String literal = "Literal";
		String s1 = new String();
		String s2 = new String("First parameter");
		
		//byte array as parameter
		byte[] byteArray = {'1','2','3'};
		String s3 = new String(byteArray);
		//Charset as 2nd parameter
		String s31 = new String(byteArray, Charset.defaultCharset());
		//Charset name as String
		String s32 = new String(byteArray, "Cp1252");
		//Offset
		String s33 = new String(byteArray, 1, 2);
		//Offset with charset
		String s34 = new String(byteArray, 1, 2, Charset.defaultCharset());
		//Offset with String charset
		String s35 = new String(byteArray, 1, 2, "Cp1252");
		
		//char array as parameter
		char[] charArray = {'1','2','3'};
		String s4 = new String(charArray);
		
		//StringBuffer as parameter
		StringBuffer buff = new StringBuffer("StrBuffer");
		String s5 = new String(buff);
		
		//StringBuilder as parameter
		StringBuilder bld = new StringBuilder("StrBuilder");
		String s6 = new String(bld);
		
		//int array
		int[] intArray = {'a', 'b', 'c'};
		String s7 = new String(intArray, 1, 2);
		
		System.out.println("s1 = " + s1);
		System.out.println("s2 = " + s2);
		System.out.println("s3 = " + s3);
		System.out.println("s31 = " + s31);
		System.out.println("s32 = " + s32);
		System.out.println("s33 = " + s33);
		System.out.println("s34 = " + s34);
		System.out.println("s35 = " + s35);
		System.out.println("s4 = " + s4);
		System.out.println("s5 = " + s5);
		System.out.println("s6 = " + s6);
		System.out.println("s7 = " + s7);
	}
}

Output will be

s1 = 
s2 = First parameter
s3 = 123
s31 = 123
s32 = 123
s33 = 23
s34 = 23
s35 = 23
s4 = 123
s5 = StrBuffer
s6 = StrBuilder
s7 = bc

Note: Constructor which takes in byteArray and charset as String as parameter, throws UnsupportedEncodingException. Also, the third parameter is the length parameter starting from offset. If the length provided is greater than the length of the string, it will throw a runtime exception StringIndexOutOfBoundsException.