$ java Upgrade      (JDK 25)
java.version = 25.0.4.1
"hello" (literal)                              length=5  coder=0  byte[].length=5
"h\u00E9llo" (e-acute, Latin-1 supplement)     length=5  coder=0  byte[].length=5
"h\u20ACllo" (euro sign)                       length=5  coder=1  byte[].length=10
"hello" + "\u20AC" (concat)                    length=6  coder=1  byte[].length=12
wide = "\u20ACabcdef"                          length=7  coder=1  byte[].length=14
wide.substring(1)  (all Latin-1 again)         length=6  coder=0  byte[].length=6
wide.replace('\u20AC', 'E')                    length=7  coder=0  byte[].length=7
wide.toLowerCase()                             length=7  coder=1  byte[].length=14
new String("caf\u00E9".getBytes(UTF_8), UTF_8) length=4  coder=0  byte[].length=4
new String(utf8 bytes of ASCII, UTF_8)         length=5  coder=0  byte[].length=5
new String(char[] {'a','b'})                   length=2  coder=0  byte[].length=2
new String(char[] {'a','\u4E2D'})              length=2  coder=1  byte[].length=4
"\uD83D\uDE00" (emoji, a surrogate pair)       length=2  coder=1  byte[].length=4
StringBuilder("ascii only").toString()         length=10  coder=0  byte[].length=10
... after append('\u20AC'), toString()         length=11  coder=1  byte[].length=22
... after setLength(0) + ASCII, toString()     length=13  coder=0  byte[].length=13
length() of the emoji: 2 (UTF-16 code units, not code points)

$ java -XX:-CompactStrings Upgrade      (JDK 25)
java.version = 25.0.4.1
"hello" (literal)                              length=5  coder=1  byte[].length=10
"h\u00E9llo" (e-acute, Latin-1 supplement)     length=5  coder=1  byte[].length=10
"h\u20ACllo" (euro sign)                       length=5  coder=1  byte[].length=10
"hello" + "\u20AC" (concat)                    length=6  coder=1  byte[].length=12
wide = "\u20ACabcdef"                          length=7  coder=1  byte[].length=14
wide.substring(1)  (all Latin-1 again)         length=6  coder=1  byte[].length=12
wide.replace('\u20AC', 'E')                    length=7  coder=1  byte[].length=14
wide.toLowerCase()                             length=7  coder=1  byte[].length=14
new String("caf\u00E9".getBytes(UTF_8), UTF_8) length=4  coder=1  byte[].length=8
new String(utf8 bytes of ASCII, UTF_8)         length=5  coder=1  byte[].length=10
new String(char[] {'a','b'})                   length=2  coder=1  byte[].length=4
new String(char[] {'a','\u4E2D'})              length=2  coder=1  byte[].length=4
"\uD83D\uDE00" (emoji, a surrogate pair)       length=2  coder=1  byte[].length=4
StringBuilder("ascii only").toString()         length=10  coder=1  byte[].length=20
... after append('\u20AC'), toString()         length=11  coder=1  byte[].length=22
... after setLength(0) + ASCII, toString()     length=13  coder=1  byte[].length=26
length() of the emoji: 2 (UTF-16 code units, not code points)
