Я думаю, что это так, потому что, поскольку 1 байт является наименьшим блоком памяти, который можно использовать в качестве заполнителя, и он не может дать нулевой размер, так как невозможно создать массив объектов.
и то, что вы сказали: «Это было немного удивительно для меня, поскольку я ожидал, что он будет иметь размер машинного слова (32 бита или 4 байта)». будет истинным для ссылочной переменной (слова macine) типа empty (), а не для самого класса (который является абстрактным типом данных),
] [] равно[
] метод [] StringBuffer[
] не переопределен из [] Object[
], так что это просто ссылочное равенство, т.е. то же самое, что и при использовании []==[
]. Я подозреваю, что причина этого в том, что []StringBuffer[
] модифицируемый, и переопределение []equals[
] в основном полезно для классов, похожих на значения, которые вы, возможно, захотите использовать в качестве ключей (хотя списки также имеют переопределение []equals[
], а []StringBuffer[
] является своего рода списком, так что это немного непоследовательно).[
] Вы сравниваете ссылки на объекты StringBuffer, а не на реальные строки внутри StringBuffer.[
] [][]System.out.println(sb1.toString().equals(sb2.toString()))[
] вернет true, и я предполагаю, что это то, чего вы ожидали или хотели достичь.[
] оба сравнивают две ссылки на объекты (sb1 - одна, а sb2 - вторая), таким образом, обе они разные.[
] [] Если вы пытаетесь сравнить содержимое - используйте метод [] compareTo(. ...)[] в классе []String[] - то есть - сначала получим []String[] содержимое []StringBuffer[] с помощью метода []toString()[] ([]. toString().compareTo[]).[
] []Ps. начиная с JDK 5, существует еще один гораздо более быстрый класс, который ведет себя точно так же, как []StringBuffer[] - это []StringBuilder[][], а также[], но он не является потокобезопасным. [
StringBuffer sb1 = new StringBuffer("Java");
StringBuffer sb2 = new StringBuffer("Java");
System.out.println(sb1.toString().compareTo(sb2.toString()));
] ][]StringBuffer[
] похоже не имеет собственного метода []равно[
], так что мое первое предположение было бы, что []StringBuffer[
] наследует []равно[
] метод []Object[
], который сравнивает с использованием []sb1 == sb2[
]. Таким образом, оба метода дают один и тот же результат.[
Интересно, почему StringBuffer
не отменяет метод равно
. Вероятно, потому, что содержимое объекта получено методом toString()
и имеет желаемый метод.
Простой ответ заключается в том, что StringBuffer
(и StringBuilder
) не отменяют базовую семантику Object.equals ()
. Таким образом, равно
в StringBuffer
будет просто сравнивать ссылки на объекты.
Фактически, String
, StringBuffer
, StringBuilder
и CharBuffer
реализуют интерфейс CharSequence и javadoc для этого интерфейса говорит следующее:
Этот интерфейс не уточняет общие контракты методов
равно
иhashCode
. Таким образом, результат сравнения двух объектов, реализующихCharSequence
, в общем случае не определен. Каждый объект может быть реализован другим классом, и нет гарантии, что каждый класс сможет проверить свои экземпляры на равенство с экземплярами другого. Поэтому нецелесообразно использовать произвольные экземплярыCharSequence
в качестве элементов в наборе или в качестве ключей на карте.
Также обратите внимание, что javadocs для StringBuffer
(и StringBuilder
) явно заявляет следующее:
Примечание API:
StringBuffer
реализуетComparable
но не отменяетравно
. Таким образом, естественный порядокStringBuffer
несовместим сравным
.Следует проявлять осторожность, если объектыStringBuffer
используются как ключи вSortedMap
или элементы вSortedSet
.
Но почему?
В основе этого лежит тот факт, что String
является неизменяемым, а StringBuffer
/ StringBuilder
- изменяемым.
Если два объекта String
имеют одинаковые символы, они всегда будут иметь одинаковые символы. Поэтому естественно рассматривать их как равные ... и это то, что делает String :: equals (Object)
.
Если два объекта StringBuffer
могут иметь одинаковые символы сейчас и разные символы через мгновение ... из-за операции изменения, выполняемой другим потоком. Реализация equals (Object)
для StringBuffer
, чувствительного к (изменяющемуся) содержимому, будет проблематичной. Например:
if (buf1.equals (buf2)) {
// Сделайте что-нибудь с одним из объектов StringBuffer.
}
имеет потенциальную гонку условие. Другой пример - использование экземпляров StringBuffer
в качестве ключей в HashTable
или HashMap
.
В любом случае, очень давно было принято намеренное дизайнерское решение, согласно которому StringBuffer
и StringBuilder
не отменят Object :: equals Методы
и Object :: hashCode
.