Недавно я понял, что не до конца понимаю процесс кодирования строк Java.
Рассмотрим следующий код:
public class Main
{
public static void main(String[] args)
{
System.out.println(java.nio.charset.Charset.defaultCharset().name());
System.out.println("ack char: ^"); /* where ^ = 0x06, the ack char */
}
}
Поскольку управляющие символы интерпретируются по-разному между окнами-1252 и ISO-8859-1 , я выбрал для тестирования символ ack
.
Теперь я скомпилирую его с различными кодировками файлов, UTF-8, windows-1252 и ISO-8859-1 .Оба компилируются в одну и ту же вещь, байт за байтом, что проверено md5sum
.
Затем я запускаю программу:
$ java Main | hexdump -C
00000000 55 54 46 2d 38 0a 61 63 6b 20 63 68 61 72 3a 20 |UTF-8.ack char: |
00000010 06 0a |..|
00000012
$ java -Dfile.encoding=iso-8859-1 Main | hexdump -C
00000000 49 53 4f 2d 38 38 35 39 2d 31 0a 61 63 6b 20 63 |ISO-8859-1.ack c|
00000010 68 61 72 3a 20 06 0a |har: ..|
00000017
$ java -Dfile.encoding=windows-1252 Main | hexdump -C
00000000 77 69 6e 64 6f 77 73 2d 31 32 35 32 0a 61 63 6b |windows-1252.ack|
00000010 20 63 68 61 72 3a 20 06 0a | char: ..|
00000019
Правильно выводит 0x06
нетнезависимо от того, какая кодировка используется.
Хорошо, он все равно выводит тот же 0x06
, который будет интерпретирован как печатный символ [ACK] кодовыми страницами windows-1252.
Это приводит меняна несколько вопросов:
- Ожидается ли, что кодовая страница / кодировка компилируемого файла Java будет идентична кодировке по умолчанию системы, в которой он компилируется?Всегда ли они синонимичны?
- Скомпилированное представление не зависит от кодировки времени компиляции, так ли это на самом деле?
- Означает ли это, что строки в файлах Java могут интерпретироваться?иначе во время выполнения, если они не используют стандартные символы для текущей кодировки / локали?
- Что еще я действительно должен знать о кодировании строк и символов в Java?