Characters in Java

In Java, the character 'char' data type is used to store a single 16-bit Unicode character.

Since Unicode is a character encoding standard that covers almost all the characters, punctuations, and symbols in the world’s writing systems, this allows Java to handle characters from various languages and scripts.

Characters in Java are enclosed in single quotes (‘ ‘):

char grade = 'A';
char dollar = '$';

In the first example, the variable grade‘ is assigned the character ‘A’, and in the second example, the variable ‘dollar‘ is assigned the character ‘$’.

Working With Characters in Java

The char data type is widely used in Java for tasks involving individual characters, such as processing strings, reading characters from input sources, or manipulating characters within a text.

Common use cases of char data type include manipulating strings, loop iteration, and switch statements.

Manipulating Strings

Characters are often used in string manipulation tasks. Common tasks include extracting specific characters from a string or replacing characters within a string.

In the following example, we use the charAt() method to

public class Main {
  public static void main(String[] args) {
    String name = "Bob";
    char firstLetter = name.charAt(0);'
    System.out.println(firstLetter);
    System.out.println(name);
  }
}

Output:

B
Bob

In the above example, the charAt() method takes the index of ‘0’, which corresponds to the first letter of the ‘name’ string.

Loop Iteration

Characters are commonly used in loop iteration, especially when processing strings or arrays of characters.

public class Main {
  public static void main(String[] args) {
    String greet = "Hello!";
    for (int i = 0; i < greet.length(); i++) {
        char stringChar = greet.charAt(i);
        System.out.println(stringChar);
    }
  }
}

Output:

H
e
l
l
o
!

In the example above, we looped through the ‘greet’ string, setting the value of the char variable ‘stringChar’ to each character in the string and then printing the value of ‘stringChar’.

Switch Statements

Characters can be used in switch statements for conditional branching based on specific characters.

char grade = 'A';
switch (grade) {
    case 'A':
        System.out.println("Excellent!");
        break;
    case 'B':
        System.out.println("Good!");
        break;
    default:
        System.out.println("Not specified!");
}

Char Primitive vs Character Class

Up to this point, we have used the term ‘character’ to denote the char data type. However, this isn’t the whole story.

In addition to the char primitive data type, Java also offers the Character class. The Character class is a wrapper class; an instance of the Character class is an object that contains a char primitive, but extends the functionality available for working with it. In other words:

  • A char is a primitive type that stores a single 16-bit Unicode character.
  • The Character class is used to create an object from a char.
  • An instance of the Character class is an object that wraps a char.

We can create an object of the Character class using the ‘Character’ keyword:

public class Test { 
  public static void main(String[] args) { 
    char myChar = 'a';
    Character upperChar = Character.toUpperCase(myChar);
    System.out.println(upperChar);
  } 
}

Output:

A

In the above example, we first created a char primitive called myChar, which holds a value of ‘a’. Then we created an instance of the Character class; an object called ‘upperChar’, which holds the value of myChar transformed into uppercase. Finally, we print the value of upperChar to test if our operation worked.

The Downside of Character Class Objects

At this point you may be thinking, ‘if Character objects are more powerful than char primitives, why wouldn’t we only use them (and stop using char primitives)’? There are several reasons, but the main difference is performance.

Java makes use of two primary data structures to manage data in memory, the stack and the heap. Using the stack is incredibly fast. Primitives like chars get stored directly on the stack, and therefore are extremely fast to access and use.

Character class objects, on the other hand, get stored partially on the stack, and partially on the heap. The heap is slower, but it can store larger things like objects. More technically, the object itself gets stored in the heap while a reference to the object is stored on the stack.

When we want to access a Character object, first the pointer on the stack must be accessed and followed to the location on the heap.

This means that accessing a Character object is a much slower operation than accessing a char primitive.

We’ll cover the stack and heap in later tutorials, and this will become much clearer!