Кто-то сказал мне в случае int вместо char: поскольку char в java имеет длину всего 2 байта, что нормально для большинства символов, которые уже используются, но для определенных символов (китайских или любых других),символ представляется более чем в 2 байтах, и, следовательно, мы используем вместо него int.
Предполагая, что в данный момент вы говорите конкретно о методе Reader.read()
, утверждении "кого-то", что выдействительно: неверно .
Это правда, что некоторые кодовые точки Unicode имеют значения больше 65535 и поэтому не могут быть представлены как один Java char
.Однако API Reader
фактически создает последовательность значений Java char
(или -1), а не последовательность кодовых точек Unicode.Это ясно указано в javadoc .
Если ваш входной сигнал содержит (надлежащим образом закодированную) кодовую точку Unicode, которая больше 65535, то вам фактически потребуется дважды вызвать метод read()
чтобы увидеть это.То, что вы получите, будет суррогатной парой UTF-16;то есть два значения Java char
, которые вместе представляют кодовую точку.Фактически, это соответствует тому, как работают классы Java String, StringBuilder и StringBuffer;все они используют представление на основе UTF-16 ... со встроенными суррогатными парами.
Реальная причина, по которой Reader.read()
возвращает int
, а не char
, состоит в том, чтобы позволить ему возвратить -1
всигнал о том, что больше нет символов для чтения.Та же логика объясняет, почему InputStream.read()
возвращает int
, а не byte
.
Гипотетически, я предполагаю, что разработчики Java могли бы указать, что методы read()
выдают исключение, сигнализирующее о состоянии "конца потока".Однако это просто заменило бы один потенциальный источник ошибок (неспособность проверить результат) другим (неспособность справиться с исключением).Кроме того, исключения относительно дороги, и конец потока на самом деле не является неожиданным / исключительным событием.Короче говоря, нынешний подход лучше, IMO.
(Еще один ключ к 16-битной природе API Reader
- это сигнатура метода read(char[], ...)
. Как это будет работать с кодовыми точками, превышающими 65535?если суррогатные пары не использовались?)
РЕДАКТИРОВАТЬ
Случай DataOutputStream.writeChar(int)
кажется немного странным.Однако в javadoc четко указано, что аргумент записывается в виде 2-байтового значения.И на самом деле, реализация явно записывает только два нижних байта в базовый поток.
Я не думаю, что для этого есть все основания.В любом случае для этого есть запись в базе данных об ошибках ( 4957024 ), которая помечена как «11-Closed, Not a Defect» со следующим комментарием:
»Это не лучший дизайн или оправдание, но он слишком запятнан, чтобы мы могли его изменить. "
... что является подтверждением того, что является дефект, по крайней мере, с точки зрения дизайна.
Но это не то, что стоит суетиться, ИМО.