Unicode System in Java

Naveen AnamaneniUpdated · 5 min read

A UPI app in India shows names in Hindi, Tamil, Bengali and English, sometimes on the same screen, along with the ₹ sign. In the 1990s, most languages stored only 256 different characters, so a program could handle English or Hindi, not both. Java was designed from the start around Unicode: one numbering system for the characters of almost every language in the world.

One Number for Every Character

Unicode gives every character a number called a code point, written as U+ and a hexadecimal number:

Every character has a code point; most fit in one char, emoji need two
CharacterCode pointDecimalchars needed in Java
AU+0041651
₹U+20B983771
न (Devanagari na)U+092823441
😀U+1F6001285122

How Java Stores Characters

A Java char is a 16-bit number, so it can hold values from 0 to 65,535. Java stores text in UTF-16: characters up to 65,535 take one char; characters above that, such as most emoji, take two chars, called a surrogate pair.

Codes.java▶ Try it
public class Codes {
    public static void main(String[] args) {
        char letter = 'A';
        char rupee = '₹';
        String smile = "😀";
 
        System.out.println("A as a number: " + (int) letter);
        System.out.println("Rupee sign as a number: " + (int) rupee);
        System.out.println("Next letter after A: " + (char) (letter + 1));
        System.out.println("Emoji length in chars: " + smile.length());
        System.out.println("Emoji code points: " + smile.codePoints().count());
    }
}
Output
A as a number: 65
Rupee sign as a number: 8377
Next letter after A: B
Emoji length in chars: 2
Emoji code points: 1

How it works

  1. Line 3 stores the letter A. Line 7 casts it to int and prints its number, 65.
  2. Line 4 uses a Unicode escape, ₹, to write the rupee sign without typing it. Line 8 prints its number, 8377.
  3. Line 9 adds 1 to A and casts back to char, giving B. Characters are numbers underneath.
  4. Line 5 builds the smiling-face emoji from its two chars. length() counts chars, so it says 2; codePoints().count() counts real characters, so it says 1.

Try it yourself: print (int) 'a'. How far apart are the capital and small letters?

Unicode Escapes

You can write any character in Java source as \u followed by four hexadecimal digits: 'A' is A, '₹' is ₹. This is handy when a character is hard to type.

The compiler turns \u escapes into characters before it reads anything else, even inside comments. That's why a comment containing \u000A (a new line) can break your code in a confusing way. Write \n for a new line in strings instead.

Source Files Are UTF-8

Since Java 18, javac reads source files as UTF-8 on every operating system. You can write String greeting = "नमस्ते"; directly in your code and it compiles the same on Windows, macOS and Linux. Before Java 18, the result depended on the computer's settings.

Common Mistakes

Assuming length() counts visible characters. Emoji and some rare scripts take two chars each. Use codePoints().count() when it matters, for example to limit a name to 20 characters.

Comparing a char with a String. 'A' (single quotes) is a char; "A" (double quotes) is a String. They are different types.

Doing arithmetic on chars and forgetting the cast. 'A' + 1 is the int 66. Cast it back with (char) to get 'B'.

Practice

  1. Easy: Print the numbers for '0', '9', 'a' and 'z'. What do you notice about the digits?
  2. Harder: Write a loop-free program that prints the letters A to E by starting from 'A' and adding 1, 2, 3 and 4.

Quick check: Unicode

4 questions
1How many bits is a Java char?
2What does (int) 'A' print?
3Why can "😀".length() be 2?
4Since which version does javac read source files as UTF-8 everywhere?

Key Takeaways

Was this tutorial helpful?

Lesson 36 of 482