// sample-unicode-crlf.java: non-ASCII text, saved as UTF-8 (no BOM) with // Windows (CRLF) line endings. // Free sample from 99helpers.com/file-types/java // // javac reads CRLF and LF alike, and since Java 18 it reads source files // as UTF-8 by default. On older Java, compile with // javac -encoding UTF-8 sample-unicode-crlf.java // Don't save Java source with a byte order mark: javac stops with // "illegal character: ''". // // Run it: java sample-unicode-crlf.java // If letters show as "?", your terminal isn't set to UTF-8. final class UnicodeSample { // 1. Identifiers may use letters from any script. static final String GRÜSSE = "Grüße aus Köln"; public static void main(String[] args) { // 2. A Java String is a sequence of UTF-16 code units. length() // counts those units; codePointCount() counts characters. They // differ for emoji and other characters beyond U+FFFF. String[] samples = { "plain ASCII", GRÜSSE, "Ελληνικά", "日本語のテキスト", "مرحبا بالعالم", "emoji ☕🦀" }; for (String text : samples) { System.out.printf("%2d units %2d chars %2d UTF-8 bytes %s%n", text.length(), text.codePointCount(0, text.length()), text.getBytes(java.nio.charset.StandardCharsets.UTF_8).length, text); } // 3. A text block. Its CRLF line breaks are normalised to "\n", so // the string is the same whichever line endings the file has. String poem = """ first line second line"""; System.out.println("text block contains \\r: " + poem.contains("\r")); // 4. Unicode escapes like é are translated before anything // else, even inside comments, so a stray backslash-u followed by // hex digits in a comment can break the build. String cafe = "café"; System.out.println(cafe + " equals café: " + cafe.equals("café")); // 5. 🦀 needs two UTF-16 units (a surrogate pair), so charAt(0) // returns half a character. Use codePointAt instead. String crab = "🦀"; System.out.printf("U+%X, length %d, high surrogate: %b%n", crab.codePointAt(0), crab.length(), Character.isHighSurrogate(crab.charAt(0))); } }