Unicode в javadoc и комментарии?

Некоторые компиляторы завершились с ошибкой на не-ASCII-символах в JavaDoc и комментариях исходного кода. Какова текущая (Java 7) и будущая (Java 8 и выше) практика в отношении Unicode в исходных файлах Java? Существуют ли различия между IcedTea, OpenJDK и другими средами Java, и что диктуется спецификацией языка? Должны ли все символы, отличные от ASCII, сбрасываться в JavaDoc с помощью кодов HTML & escape? Но каков будет эквивалент Java//comment?

Обновить: комментарии указывают, что можно использовать любой набор символов, а при компиляции нужно указать, какой набор char используется в исходном файле. Я рассмотрю это и буду искать подробные сведения о том, как настроить это с помощью Ant, Eclipse и Maven.

Ответ 1

Некоторые компиляторы завершились с ошибкой на не-ASCII-символах в JavaDoc и комментариях исходного кода.

Это, вероятно, потому, что компилятор предполагает, что вход UTF-8, и в исходном файле есть недопустимые последовательности UTF-8. То, что они выглядят в комментариях в редакторе исходного кода, не имеет значения, потому что lexer (который отличает комментарии от других токенов) никогда не запускается. Сбой происходит, когда инструмент пытается преобразовать байты в символы до запуска lexer.


Страница man для javac и javadoc скажет

-encoding name
          Specifies  the  source  file  encoding   name,   such   as
          EUCJIS/SJIS.   If  this option is not specified, the plat-
          form default converter is used.

поэтому запустите javadoc с флагом кодирования

javadoc -encoding <encoding-name> ...

после замены <encoding-name> на кодировку, которую вы использовали для ваших исходных файлов, должна заставить ее использовать правильную кодировку.

Если у вас есть несколько кодов, используемых в группе исходных файлов, которые вам нужно собрать вместе, вам необходимо исправить это сначала и установить единую унифицированную кодировку для всех исходных файлов. Вы действительно должны использовать UTF-8 или придерживаться ASCII.


Какова текущая (Java 7) и будущая (Java 8 и выше) практика в отношении Unicode в исходных файлах Java?

Алгоритм работы с исходным файлом в Java -

  • Сбор байтов
  • Преобразование байтов в символы (UTF-16) с использованием некоторой кодировки.
  • Замените все последовательности '\\' 'u', а затем четыре шестнадцатеричных цифры с кодовым блоком, соответствующим этим шестнадцатеричным цифрам. Ошибка, если есть "\u", за которым не следуют четыре шестнадцатеричных цифры.
  • Вставьте символы в токены.
  • Разделите маркеры на классы.

Текущая и прежняя практика заключается в том, что шаг 2, преобразование байтов в кодовые единицы UTF-16, зависит от инструмента, который загружает блок компиляции (исходный файл), но фактический стандарт для интерфейсов командной строки - использовать -encoding.

После этого преобразования язык указывает, что последовательности стилей \uABCD преобразуются в кодовые единицы UTF-16 (шаг 3) перед лексированием и разбором.

Например:

int a;
\u0061 = 42;

- действительная пара операторов Java. Любой инструмент исходного кода Java должен после преобразования байтов в символы, но до разбора, искать последовательности \uABCD и преобразовывать их, чтобы этот код был преобразован в

int a;
a = 42;

перед синтаксическим разбором. Это происходит независимо от того, где происходит последовательность \uABCD.

Этот процесс выглядит примерно так:

  • Получить байты: [105, 110, 116, 32, 97, 59, 10, 92, 117, 48, 48, 54, 49, 32, 61, 32, 52, 50, 59]
  • Преобразование байтов в символы: ['i', 'n', 't', ' ', 'a', ';', '\n', '\\', 'u', '0', '0', '6', '1', ' ', '=', ' ', '4', '2', ';']
  • Заменить unicode escapes: ['i', 'n', 't', ' ', 'a', ';', '\n', a, ' ', '=', ' ', '4', '2', ';']
  • Лекс: ["int", "a", ";", "a", "=", "42", ";"]
  • Анализ: (Block (Variable (Type int) (Identifier "a")) (Assign (Reference "a") (Int 42)))

Должны ли все символы, отличные от ASCII, сбрасываться в JavaDoc с помощью кодов HTML & escape;?

Нет необходимости, кроме специальных символов HTML, таких как '<', которые вы хотите буквально представить в документации. Вы можете использовать последовательности \uABCD в комментариях javadoc. Java process \u.... перед разбором исходного файла, чтобы они могли отображаться внутри строк, комментариев и в любом месте. Вот почему

System.out.println("Hello, world!\u0022);

является допустимым оператором Java.

/** @return \u03b8 in radians */

эквивалентно

/** @return θ in radians */

в отношении javadoc.


Но какой будет эквивалент комментария Java //?

Вы можете использовать комментарии // в java, но Javadoc просматривает только комментарии /**...*/ для документации. // комментарии не содержат метаданные.

Одним из ветвей обработки Java из \uABCD последовательностей является то, что хотя

// Comment text.\u000A System.out.println("Not really comment text");

выглядит как комментарий одной строки, и многие IDE будут выделять его как таковые, это не так.

Ответ 2

Как отмечали комментаторы, кодирование исходных файлов может быть передано (по крайней мере некоторым) компиляторам. В этом ответе я расскажу, как передать эту информацию.

Eclipse,

Eclipse (3.7 проверено) не требует специальной настройки, и вы можете с радостью использовать исходный код Java, например:

double π = Math.PI;

Ant

<javac encoding="UTF-8" ... >
</javac>

Java

javac -encoding UTF-8 src/main/Foo.java