2012-03-19 3 views
8

Различия между StringBuilder и StringBuffer в Java хорошо документированы и были также touched upon in StackOverflow.Почему бы не создать StringBuilder и StringBuffer общий интерфейс?

В принципе, StringBuilder является несинхронизированной копией StringBuffer, с почти таким же интерфейсом, поскольку она была предназначена для более быстрой замены на StringBuffer. Их API практически идентичен, и они фактически являются подклассами того же недоступным абстрактным классом в текущем JDK.

Единственное, о чем я спрашиваю, поэтому, почему они не являются публично связанными. Наличие обоих классов реализует общий интерфейс или даже имеет StringBuffer в качестве подкласса StringBuilder, что бы иметь смысл, позволяя существование общего кода для обоих классов.

Итак, почему это принудительное разделение? Это было так, что программисты не могли бы случайно смешать потокобезопасность с помощью небезопасного кода? Или это был просто надзор за дизайном, который теперь будет унаследован до конца вечности?

EDIT:

Чтобы сделать вещи ясно: я могу спекулировать о том, почему вещи, как это, но я надеюсь на конкретные ссылки на фактическое решение, например, во время процесса JSR. Все, что могло бы пролить свет на то, что для меня представляет собой ситуацию, которая иногда вызывает определенную трудность.

EDIT 2:

Тот факт, что оба класса реализации Appendable полностью запамятовал. Вероятно, потому что этот конкретный интерфейс бесполезен для большинства целей - он может только добавить один символ или подготовленный объект, и все. В большинстве случаев это не более полезно, чем оба класса являются подклассами Object.

EDIT 3:

Ну, вот обоснование именно этот вопрос от a semi-official source:

Оценки команды библиотек:

Это дизайн, что StringBuffer и StringBuilder доля нет общий публичный супертип. Они не предназначены для альтернатив: одна - ошибка (StringBuffer), а другая (StringBuilder) - ее замена .

Очевидно, что отсутствие общего супертипа может в некоторых случаях замедлить переход от StringBuffer к StringBuilder с ожидаемым переносом. Оборотная сторона заключается в том, что добавив общий супертип, мы будем принимать ошибки нашего прошлого и закреплять их в открытом интерфейсе, чтобы быть с нами для всех времени. Это не просто замедляет миграцию: это сводит на нет ее.

ответ

3

У меня нет ссылки на JSR, но из моего опыта. Ниже приводятся несколько причин:

  • StringBuffer как подкласса из StringBuilderне является хорошей идеей для повышения производительности. Чтобы сделать потоки StringBuffer, вам нужно замаскировать каждый звонок до StringBuilder, который много накладных расходов.

  • Добавление к выше точкам, можно дополнительно оптимизировать, если у вас есть прямой доступ через внутренности класса, что является причиной, почему Java добавил java.lang.concurrent над java.util.Collections.synchronized* APIs. Поскольку более прямой доступ дает больше возможностей для оптимизации. Для SUPORT этой точки Reference from the IBM blog

  • Далее добавления к первой точке, я не думаю, что это дизайн надзор, поскольку оба эти классы final так определенно они не хотят, чтобы эти классы должны быть подклассы.

  • Что касается тех же интерфейсов, оба класса реализуют те же интерфейсы, что и Serializable, Appendable, CharSequence. Таким образом, они заменяются. Единственное, что они не реализуют один общий интерфейс, а вместо этого три общих интерфейса. Что имеет смысл, так как нет необходимости иметь один раздутый интерфейс, который технически будет представлять собой сумму текущих интерфейсов (Serializable, Appendable, CharSequence).

РЕДАКТИРОВАТЬ:

  • Для @MatthewFlaschen точки, что есть интерфейсы, которые являются такими же, ч/б StringBuffer и StringBuilder но не в какой-либо из реализованных интерфейсов. Это больше связано с обратной совместимостью. Вы хотите добавить новый api, но интерфейс используется многими другими классами, поэтому изменение интерфейса может оказаться невозможным soln. Это хорошо продуманное решение, которое могли бы сделать Java-ребята. Поэтому я не скажу, что это ошибка.

EDIT 2:

SIDE ПРИМЕЧАНИЕ: Другое дело, следует отметить, что StringBuffer был введен в 1,0 и StringBuilder в 1,5 раза. Таким образом, apis, который присутствует в обоих классах, но не в интерфейсах, вводится позже, а не во время создания этих слишком классов.

+0

Существуют способы, например. append (long), которые находятся в обоих классах, но ни один из интерфейсов. –

+0

Хотя я думаю, что как Vector и ArrayList расширяют AbstractList, StringBuffer и StringBuilder могли бы расширить аналогичный абстрактный класс. Я не смотрел на самый последний источник, но StringBuilder, похоже, был прямым тиражом StringBuffer за вычетом синхронизации. –

+0

@MatthewFlaschen append() из Appendable. –

2

Они на самом деле оба выполняют Appendable.

Я не согласен с тем, что это бесполезно.По моему опыту, большая часть использования StringBuilder/StringBuffer имеет дело со строками (которые реализуют CharSequence). Для остатка вы можете позвонить String.valueOf, прежде чем передать его.

Было бы удобно, если бы был другой интерфейс, который также имел другие методы, такие как append(long). Но это не обязательно.

Было бы разумно иметь общий интерфейс. Они имеют разные характеристики производительности и потоков, но это прекрасно и верно для многих интерфейсов в JDK.

Например, CopyOnWriteArrayList в поточно-список на базе массива (это делает новый список для каждой записи), в то время как LinkedList не является поточно-связанный список.

+0

Вы не ответили на вопрос или даже не дали понять, почему это возможно. – FriendlyGuy

+0

@MackieChan, я не согласен. Я сказал: «Было бы разумно иметь общий интерфейс». Это еще один способ сказать: «Да, это надзор за дизайном». –

+0

Честно говоря, Appendable поскользнулся, в основном потому, что я регулярно добавляю числа e.t.c. в моем коде. Я действительно не считаю этот конкретный интерфейс очень полезным, потому что он заставляет вас сначала преобразовать все в строку. Не говоря уже о том, что существующее содержимое является неизменным ... – thkala