Почему параметр для метода string.indexOf является int в Java - PullRequest
8 голосов
/ 02 июня 2011

Мне интересно, почему для параметра indexOf вызывается метод int, когда в описании написано char.

public int indexOf (int ch)

Returns the index within this string of the first occurrence of the specified **character**

http://download.oracle.com/javase/1,5.0/docs/api/java/lang/String.html#indexOf%28int%29

Also, both of these compiles fine:
char c = 'p';
str.indexOf(2147483647);
str.indexOf(c);

a] По сути, меня смущает то, что int в Java является 32-битным, а символы Юникода 16-битными.

b] Почему бы не использовать самого персонажа вместо использования int. Это какая-то оптимизация производительности? Трудно ли представить символы, чем int? Как?

Полагаю, это должно быть простым объяснением, и это заставляет меня знать об этом еще больше!

Спасибо!

Ответы [ 4 ]

13 голосов
/ 02 июня 2011

Причина real в том, что indexOf(int) ожидает кодовую точку Unicode, а не 16-битный UTF-16 "символ". Кодовые точки Unicode на самом деле имеют длину до 21 бита.

(Представление UTF-16 более длинной кодовой точки на самом деле представляет собой 2 16-разрядных «символьных» значения. Эти значения известны как начальные и конечные суррогаты; D800 16 до DBFF 16 и DC00 16 до DFFF 16 соответственно; см. Unicode FAQ - UTF-8, UTF-16, UTF-32 и BOM для подробностей. )

Если вы дадите indexOf(int) кодовую точку> 65535, она будет искать пару символов UTF-16, которые кодируют кодовую точку.

Об этом говорится в javadoc (хотя и не очень четко), и изучение кода показывает, что этот метод действительно реализован.


Почему бы просто не использовать 16-битные символы?

Это довольно очевидно. Если бы они это сделали, не было бы простого способа найти кодовые точки больше 65535 в строках. Это было бы серьезной проблемой для людей, которые разрабатывают интернационализированные приложения, где текст может содержать такие кодовые точки. (Многие предположительно интернационализированные приложения ошибочно предполагают, что char представляет собой кодовую точку. Часто это не имеет значения, но все чаще и чаще.)

Но это не должно иметь никакого значения для вас. Метод по-прежнему будет работать, если ваши строки состоят только из 16-битных кодов ... или, в этом отношении, только из кодов ASCII.

4 голосов
/ 02 июня 2011

Символы в Java хранятся в их целочисленном представлении в юникоде. Документация класса Character содержит более подробную информацию об этом формате.

Из документов на этой странице:

Методы, принимающие значение типа int, поддерживают все символы Unicode, включая дополнительные символы. Например, Character.isLetter (0x2F81A) возвращает true, поскольку значение кодовой точки представляет букву (идеограф CJK).

0 голосов
/ 02 июня 2011

В Java есть целый ряд неявных правил приведения типов, выполняемых под капотом.Для примитивов существуют специальные правила, которые изложены в документе Конверсии и рекламные акции , являющемся частью документации Sun по Java.По вашему конкретному вопросу преобразование int в char - это «сужающее примитивное преобразование».См. Раздел 5.1.3 в приведенном выше документе.

При этом общепринятая практика программирования заключается в обмене небольшими положительными целыми числами и символами, которые кодируются как целые числа.Это восходит к их неразличимому использованию в C, когда ASCII был всем, что существовало.

0 голосов
/ 02 июня 2011

Метод str.indexOf(int) принимает int. Если вы передадите ему char, java преобразует char в int, поскольку char - это 16-битное число.

...