Java String Basics and Why Strings Are Immutable
Introduction
Text is everywhere in programs - names, messages, file contents, web pages - and in Java, text is handled by the String class. This tutorial covers Java String basics and why strings are immutable. We will start with what a
(Note - String literals, including escape sequences such as
OUTPUT of the above code
Explanation of the code
Joining strings
The
OUTPUT of the above code
OUTPUT of the above code
Note that
Strings are immutable
A
OUTPUT of the above code
Explanation of the code
String is, and the ways to create one. We will then join strings together, and look at strings as sequences of characters. Next we will understand what it means that strings are immutable, and see why "changing" a string really creates a new one. Lastly, we will look at why Java's designers made strings immutable, and the main consequences for your code.(Note - String literals, including escape sequences such as
\n, are covered in Java LiteralsClick to read tutorial: Java Literals: Integer, Floating-Point, char and boolean.)
What is a String?
A String is a sequence of characters, such as "Hello". In Java, String is a class in the java.lang package, not a primitive type - so a String variable holds a reference to a String object, and can be null. But strings are so important that the language gives them special support -- String literals: text in double quotes creates a
Stringobject, withoutnew. - The + operator: joins strings together - the only operator Java overloads for a class.
- The string pool: identical string literals share one object, which saves memory. See the Java String poolClick to read tutorial: Java String Pool: String Literals vs new String().
Ways to create a String
//CreatingStrings.java
public class CreatingStrings {
public static void main(String[] args) {
String literal = "Java"; // from a literal - the usual way
String withNew = new String("Java"); // with new - rarely needed
char[] letters = {'J', 'a', 'v', 'a'};
String fromChars = new String(letters); // from a char array
String fromNumber = String.valueOf(3.14); // from a number
String repeated = "ab".repeat(3); // from another string's method
String empty = ""; // the empty string
String nothing = null; // no String object at all
System.out.println(literal + " " + withNew + " " + fromChars + " " + fromNumber + " " + repeated);
System.out.println("empty has length " + empty.length() + ", isEmpty: " + empty.isEmpty());
System.out.println("nothing = " + nothing);
}
}
Java Java Java 3.14 ababab empty has length 0, isEmpty: true nothing = null
- Create strings from literals whenever you can.
new String("Java")creates an extra, unneeded object. - The empty string
""is a realStringobject with length 0.nullmeans there is no object at all - callingnothing.length()would throw aNullPointerException. - Joining
nullto a string with+does not fail - it adds the textnull.
+ operator joins (concatenates) strings. If either side of + is a String, the other side is converted to text - numbers, booleans and objects alike. concat() and String.join() are alternatives.
Joining strings
//JoiningStrings.java
public class JoiningStrings {
public static void main(String[] args) {
String first = "Tom";
String last = "Jones";
String full = first + " " + last;
System.out.println(full);
int age = 32;
System.out.println(full + " is " + age + " years old");
System.out.println("Total: " + 10 + 20);
System.out.println("Total: " + (10 + 20));
System.out.println(first.concat(last));
System.out.println(String.join(", ", "Tom", "Harry", "Ethan"));
}
}
Tom Jones Tom Jones is 32 years old Total: 1020 Total: 30 TomJones Tom, Harry, Ethan
"Total: " + 10 + 20 printed Total: 1020, because + works from left to right, and once the left side is a string, every + joins text. Parentheses make the addition happen first. See operator precedenceClick to read tutorial: Java Operator Precedence and Associativity Explained.
A String is a sequence of characters
Each character of a string has an index, starting at 0, just like an array. length() gives the number of characters, and charAt(i) gives the character at index i.
Characters and indexes in a String
//StringChars.java
public class StringChars {
public static void main(String[] args) {
String word = "Brahman";
System.out.println("Length: " + word.length());
System.out.println("First: " + word.charAt(0) + ", last: " + word.charAt(word.length() - 1));
int vowels = 0;
for (int i = 0; i < word.length(); i++) {
char c = Character.toLowerCase(word.charAt(i));
if ("aeiou".indexOf(c) >= 0) {
vowels++;
}
}
System.out.println("Vowels: " + vowels);
try {
System.out.println(word.charAt(7));
} catch (StringIndexOutOfBoundsException e) {
System.out.println("charAt(7) failed: " + e.getMessage());
}
}
}
Length: 7 First: B, last: n Vowels: 2 charAt(7) failed: Index 7 out of bounds for length 7
length() is a method for strings - with parentheses - while arrays use the field length. As with arrays, an index outside 0 to length() - 1 throws an exception, here a StringIndexOutOfBoundsException. (The try and catch blocks catch the exception so that we can print its message; exception handling is covered later in this series.)
String object can never be changed after it is created. It has no method which modifies its characters. Methods which seem to change a string - toUpperCase(), replace(), trim(), concat() - all return a new String, and leave the original untouched.
Strings cannot be changed
//Immutability.java
public class Immutability {
public static void main(String[] args) {
String name = "java";
name.toUpperCase(); // result thrown away
System.out.println("After toUpperCase(): " + name);
String upper = name.toUpperCase(); // keep the new String
System.out.println("upper = " + upper + ", name = " + name);
String greeting = "Hello";
String alias = greeting; // both refer to the same object
greeting = greeting + ", World"; // greeting now refers to a NEW object
System.out.println("greeting = " + greeting);
System.out.println("alias = " + alias);
}
}
After toUpperCase(): java upper = JAVA, name = java greeting = Hello, World alias = Hello
name.toUpperCase()on its own did nothing useful - it created"JAVA", but the result was not stored. This is a very common beginner bug. Always use the returned value.greeting = greeting + ", World"did not change the"Hello"object. It created a new"Hello, World"object and pointedgreetingat it.aliasstill refers to the unchanged"Hello".- The variable
greetingcan be reassigned - it is notfinal. It is the object which is immutable.
- Sharing is safe: because no one can change a string, the same object can be shared freely - between variables, between methods, and in the string pool. A method which receives a string can be sure it will not change under it.
- Security: strings hold file names, URLs, user names and class names. If they could be changed after being checked, a value could be altered between a security check and its use.
- Thread safety: immutable objects can be used by many threads at once without any locking.
- Hashing: a string's hash code can be calculated once and cached, which makes strings fast and reliable as keys in a
HashMapor elements of aHashSet.
String is a class with special language support - literals, the + operator and the string pool. We then created strings in several ways, and saw the difference between the empty string and null. Next we joined strings with +, concat() and String.join(), and treated a string as a sequence of characters with length() and charAt(). We then saw that strings are immutable - methods return new strings, and reassigning a variable does not change the original object. Lastly, we went through the reasons for immutability, and its cost. In the next tutorial, we will look at the String poolClick to read tutorial: Java String Pool: String Literals vs new String().Java Fundamentals Tutorials
Common Java Array Programs with ExamplesClick to read tutorial: Common Java Array Programs with Examples Java String Pool: String Literals vs new String()Click to read tutorial: Java String Pool: String Literals vs new String() Java String Comparison: == vs equals() vs compareTo()Click to read tutorial: Java String Comparison: == vs equals() vs compareTo() Essential Java String Methods with ExamplesClick to read tutorial: Essential Java String Methods with Examples String vs StringBuilder vs StringBuffer in JavaClick to read tutorial: String vs StringBuilder vs StringBuffer in Java Java Text Blocks: Multi-line Strings with ExamplesClick to read tutorial: Java Text Blocks: Multi-line Strings with Examples Common Java String Programs with ExamplesClick to read tutorial: Common Java String Programs with Examples
Common Java Array Programs with ExamplesClick to read tutorial: Common Java Array Programs with Examples Java String Pool: String Literals vs new String()Click to read tutorial: Java String Pool: String Literals vs new String() Java String Comparison: == vs equals() vs compareTo()Click to read tutorial: Java String Comparison: == vs equals() vs compareTo() Essential Java String Methods with ExamplesClick to read tutorial: Essential Java String Methods with Examples String vs StringBuilder vs StringBuffer in JavaClick to read tutorial: String vs StringBuilder vs StringBuffer in Java Java Text Blocks: Multi-line Strings with ExamplesClick to read tutorial: Java Text Blocks: Multi-line Strings with Examples Common Java String Programs with ExamplesClick to read tutorial: Common Java String Programs with Examples