Подскажите, в чем принципиальное отличие между этими объектами? В каких случаях оптимально использовать CharSequence?
Ответ 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, то его еще можно и раскрасить.