Недавно я понял, что я не полностью понимаю процесс кодирования строки 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
char для тестирование.
Теперь я скомпилирую его с различными кодировками файлов, 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] char кодами-окнами windows-1252.
Это приводит меня к нескольким вопросам:
- Является ли кодовая страница/кодировка скомпилированного файла Java ожидаемой идентичной кодировке по умолчанию системы, в которой она компилируется? Являются ли эти два синонимами?
- Скомпилированное представление, похоже, не зависит от кодировки времени компиляции, действительно ли это так?
- Означает ли это, что строки в файлах Java могут интерпретироваться по-разному во время выполнения, если они не используют стандартные символы для текущей кодировки/локали?
- Что еще я должен знать о кодировке строк и символов в Java?