Когда использовать CharSequence в API
Я разрабатываю публичный интерфейс (API) для пакета. Интересно, следует ли использовать CharSequence
вместо String
. (Я в основном говорю об открытых интерфейсах).
Есть ли недостатки в этом? Является ли это хорошей практикой?
Как использовать его для целей, подобных идентификаторам (когда значение сопоставляется с набором в контейнере на основе хэша)?
Ответы
Ответ 1
CharSequence
редко используется в библиотеках общего назначения. Его обычно следует использовать, когда ваш основной вариант использования - обработка строк (манипуляция, разбор,...).
Вообще говоря, вы можете делать что-либо с CharSequence
, которое вы могли бы сделать с помощью String
(тривиально, так как вы можете конвертировать каждый CharSequence
в String
). Но существует одно важное различие: A CharSequence
не гарантируется неизменным! Всякий раз, когда вы обрабатываете String
и проверяете его в два разных момента времени, вы можете быть уверены, что он будет иметь одинаковое значение каждый раз.
Но для a CharSequence
это не обязательно верно. Например, кто-то может передать StringBuilder
в свой метод и изменить его, пока вы что-то делаете с ним, что может сломать много разумного кода.
Рассмотрим этот псевдокод:
public Object frobnicate(CharSequence something) {
Object o = getFromCache(something);
if (o == null) {
o = computeValue(something);
putIntoCache(o, something);
}
return o;
}
Это выглядит достаточно безвредным, и если бы вы использовали String
здесь, он работал бы в основном (за исключением того, что значение могло быть рассчитано дважды). Но если something
является CharSequence
, то его содержимое может меняться между вызовом getFromCache
и вызовом computeValue
. Или еще хуже: между вызовом computeValue
и вызовом putIntoCache
!
Следовательно: только принять CharSequence
, если есть большие преимущества, и вы знаете недостатки.
Если вы принимаете CharSequence
, вы должны указать, как ваш API обрабатывает изменяемые объекты CharSequence
. Например: "Изменение аргумента, когда метод выполняет результаты в undefined".
Ответ 2
Java CharSequence
- это интерфейс. Как говорит API, CharSequence
был реализован в классах CharBuffer
, Segment
, String
, StringBuffer
, StringBuilder
. Поэтому, если вы хотите получить или принять свой API от all этих классов, тогда CharSequence
- ваш выбор. Если нет, то String
очень хорошо подходит для публичного API, потому что это очень легко, и все об этом знают. Помните, что CharSequence
предоставляет только 4 метода, поэтому, если вы принимаете объект CharSequence
с помощью метода, то ваша способность к обработке ввода будет ограничена.
Ответ 3
Это зависит от того, что вам нужно, однако я хотел бы указать два преимущества String
.
Из CharSequence
документация:
Каждый объект может быть реализован другим классом, и нет гарантировать, что каждый класс сможет проверить свои экземпляры для равенство с другим. Поэтому нецелесообразно использовать произвольные экземпляры CharSequence как элементы в наборе или как ключи в карта.
Таким образом, всякий раз, когда вам нужен Map
или надежный equals
/hashCode
, вам нужно скопировать экземпляры в String
(или что-то еще).
Более того, я думаю, что CharSequence
явно не упоминает, что реализации должны быть неизменными. Вам может потребоваться защитное копирование, которое может замедлить ваши реализации.
Ответ 4
Если параметр концептуально представляет собой последовательность символов, используйте CharSequence.
Строка технически представляет собой последовательность символов, но чаще всего мы не думаем об этом; строка более атомарная/целостная, мы обычно не заботимся о отдельных символах.
Подумайте о int - хотя int - это технически последовательность бит, мы обычно не заботимся о отдельных битах. Мы манипулируем int как атомные вещи.
Итак, если основная работа, которую вы собираетесь делать по параметру, - это итерация по своим символам, используйте CharSequence. Если вы собираетесь манипулировать параметром как атомарная вещь, используйте String.
Ответ 5
Вы можете реализовать CharSequence
для хранения ваших паролей, потому что использование String
не рекомендуется для этой цели. Реализация должна иметь метод удаления, который уничтожает данные обычного текста.