How Java works

Pick a topic, write code and watch what happens inside, step by step.

Memory

Collections

Concurrency

Language and JVM

Topics

String inside

What is inside a String?

Since Java 9, String holds a byte[], not a char[]. coder says how to read the bytes.

A final array alone does not make it immutable: value is private and no method changes it. Every "change" creates a new String.

hash is computed on the first hashCode() and then kept, which makes String a good HashMap key.

LATIN1 or UTF16?

If every character is below 256, each takes 1 byte: Compact Strings. One larger character moves the whole String to 2 bytes each.

Azerbaijani shows this often: ç, ö, ü are in LATIN1, but ə, ş, ğ, ı are not.

"çörek" takes 5 bytes and "çörək" takes 10. The difference is one letter.

length() does not count symbols

length() counts chars, and a char is 16 bits. Emojis do not fit in 16 bits and take two chars: a surrogate pair.

To count the symbols a person sees, use codePointCount. Combined forms, such as flags and family emojis, are made of several code points.

When is the array shared?

new String(a) creates a new object but does not copy the value array: since it is immutable, sharing is safe.

substring always creates a new array. It has worked this way since Java 7u6, so a small substring does not keep a big array in memory.

An interesting case: cut a LATIN1 part from a UTF16 String and the result gets compressed.

Why is += slow in a loop?

A String is immutable, so every += copies all the text into a new array. As the text grows, so does the copy: O(n²).

StringBuilder keeps one buffer and grows it only when full. Always use it in a loop.

Outside a loop, a + b + c is fine: javac turns it into one invokedynamic call.