Страницы

Поиск по вопросам

суббота, 30 ноября 2019 г.

CharSequence или String?

#java #android #строки


Подскажите, в чем принципиальное отличие между этими объектами? В каких случаях оптимально
использовать CharSequence?
    


Ответы

Ответ 1



CharSequence это интерфейс со всеми вытекающими. Под капотом может быть CharBuffer, Segment, String, StringBuffer, StringBuilder. Или собственная реализация. Чтобы было понимание приведу следующий пример: public class Main { public static void main(String[] args) { String str = new String("Hello from String"); soutString(str); } public static void soutString(String str) { System.out.println(str.getClass()); System.out.println(str); } } Метод SoutString выводит класс и содержимое строки: class java.lang.String Hello from String Если мы захотим использовать StringBuilder, то для того что бы воспользоваться методом SoutString мы должны использовать преобразование. Так как он ожидает String: StringBuilder sb = new StringBuilder("Hello from StringBuilder"); soutString(sb.toString()); Добавляем эти строки и смотрим результат: class java.lang.String Hello from String class java.lang.String Hello from StringBuilder Мы так же знаем, что String и StringBuilder реализуют интерфейс 'CharSequence' и это позволяет нам написать следующее: public class Main { public static void main(String[] args) { CharSequence str = new String("Hello from String"); soutCharSequence(str); CharSequence sb = new StringBuilder("Hello from StringBuilder"); soutCharSequence(sb); } public static void soutCharSequence(CharSequence ch) { System.out.println(ch.getClass()); System.out.println(ch); } } Вывод будет следующим: class java.lang.String Hello from String class java.lang.StringBuilder Hello from StringBuilder Отметим тот факт, что во втором случае в метод был передан StringBuilder. Мы можем передавать в наш метод любые классы, которые реализуют интерфейс. Внутри метода можно использовать методы интерфейса, например length(); А еще мы можем внутри метода безопасно выполнить специфические для объекта действия: if (ch instanceof String) { System.out.println(((String) ch).toUpperCase()); } Я не знаток Android, но думаю, что @Barmaley хотел сказать что если передается в качестве CharSequence объект String, то будет выводится просто текст. А если объект дополнительно реализует Spannable, то его еще можно и раскрасить.

Ответ 2



Формально конечно CharSequence это интерфейс, но смысловая нагрузка CharSequence в Android обычно предполагает, что набор символов может иметь в дальнейшем некие стили - конкретно Spannable, ну например, можно сделать чтобы часть строки имел другой цвет или шрифт. Соответственно CharSequence имеет смысл использовать, если предполагается, что частям строки нужно/можно придавать определенные специальные свойства - то есть то чего нельзя добиться лобовым использованием String.

Ответ 3



CharSequence - это любой набор символов, не обязательно иммутабельный, как объект String. В этом интерфейсе определено буквально 4 метода. В android его реализуют как различные строки и их билдеры (String, StringBuilder, и т.п.), так и текст с форматированием (Spanned). Любой CharSequence можно преобразовать в строку методом .toString(), но это может быть преобразование с потерей информации. Например, если преобразовать в строку текст с форматированием (Spanned), то из него удалится всё форматирование, а если преобразовать StringBuilder, то потеряется возможность редактирования этой строки. Кроме того, такое преобразование — это почти всегда создание нового объекта. Использовать лучше везде, где достаточно 4 методов интерфейса CharSequence и не нужны возможности класса String, либо нужно сохранить свойства переданного объекта при передаче куда-то дальше. Но нужно быть осторожным. В частности, лучше не использовать метод equals() для сравнения объектов, так как он может быть не определен, либо определен не так, как вы хотели бы.

Комментариев нет:

Отправить комментарий