==
тесты для ссылочного равенства (независимо от того, являются ли они одним и тем же объектом).
.equals()
тесты для равенства значений (независимо от того, являются ли они логически «равными»).
Objects.equals () проверяет наличие null
перед вызовом .equals()
, поэтому вам не нужно (доступно с JDK7, также доступным в Guava ).
String.contentEquals () сравнивает содержимое String
с содержимым любого CharSequence
(доступно с Java 1.5).
Следовательно, если вы хотите проверить, имеет ли две строки одно и то же значение, вы, вероятно, захотите использовать Objects.equals()
.
// These two have the same value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true
// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true
Вы почти всегда хотите использовать Objects.equals()
. В редкой ситуации, когда вы знаете, что имеете дело с интернированными строками, вы можете использовать ==
.
Из JLS 3.10. 5. Строковые литералы :
Кроме того, строковый литерал всегда ссылается на тот же экземпляр класса
blockquote>String
. Это связано с тем, что строковые литералы, или, в более общем смысле, строки, которые являются значениями константных выражений ( §15.28 ), «интернированы», чтобы обмениваться уникальными экземплярами, используя методString.intern
.. Подобные примеры также можно найти в JLS 3.10.5-1 .
Это потому, что int
составляет 4 байта и должен быть выровнен по 4-байтовой границе. Это означает, что ЛЮБАЯ структура
, содержащая int
, также должна быть выровнена как минимум по 4 байтам.
С другой стороны, short
составляет 2 байта и требует выравнивания только по 2-байтовой границе. Если структура
, содержащая short
s, не содержит ничего, что требует большего выравнивания, структура
также будет выровнена по 2 байтам.
Эта ссылка должна помочь: http://en.wikipedia.org/wiki/Data_structure_alignment
В ThreeShorts
все элементы выровнены по двум байтам.
Это действительно меня озадачивает, почему не применяется выравнивание для t
Какое выравнивание вы хотите, чтобы оно было?
Шорты можно выровнять на 2-байтовых границах без вредных последствий (при условии, что здесь повсюду распространены компиляторы x86 ..). Поэтому, если вы создаете массив из struct ThreeeShorts
, эта структура размером 6 вполне подойдет, так как любые элементы в таком массиве будут начинаться с 2-байтовой границы.
Ваша struct IntAndChar
содержит int, ints требует 4-байтового выравнивания, поэтому, если вы создаете массив из struct IntAndChar
, размер должен быть 8, чтобы следующий элемент был выровнен на 4-байтовой границе.
Если бы мы не рассматривали массивы, это не имело бы большого значения, если бы длина struct IntAndChar
составляла 5 байтов, компилятор просто выделял бы его, начиная с 4-байтовой границы, когда вы создаете один в стеке. или используйте его как составной член в другой структуре.
Вы всегда можете получить количество элементов в массиве, выполнив sizeof (arrayofT) / sizeof (T), и элементы массива гарантированно будут храниться рядом друг с другом, так что n'-й элемент может быть извлечен с помощью шага N * sizeof (arrayelementtype) байтов с самого начала, и это основная причина, по которой вы увидите, что структуры заполняются в конце.
Не знаю, откуда вы взяли, что char
или int
вычисляются как «8 байт». Нет, каждый тип вычисляется в соответствии со своим размером: char
как 1, int
как 4 на 32-битной платформе (не 8, а 4). Требования к выравниванию для каждого типа обычно такие же, как и его размер (хотя это не обязательно).
По этой причине, когда структура содержит элементы того же типа , общий размер этой структуры обычно будет точной суммой размеров ее элементов: структура из 3 char
s будет иметь размер 3, а структура из двух int
s будет иметь размер 8.
Очевидно, type short
на вашей платформе имеет размер 2, поэтому, как и следовало ожидать , структура из 3 шорт имеет размер 6, что вы и наблюдаете.
Однако, когда ваша структура содержит элементы разных типов, тогда в игру вступает разница между требованиями выравнивания разных типов. Если требование выравнивания следующего поля более жесткое, чем требование выравнивания предыдущего поля, компилятору, возможно, придется добавить несколько байтов заполнения между этими полями (чтобы правильно выровнять следующий член), что повлияет на окончательный размер структуры. Кроме того, компилятору может потребоваться добавить некоторые дополнительные байты заполнения после последнего члена структуры, чтобы удовлетворить требованиям выравнивания в массиве.
Например, структура, которая выглядит следующим образом
struct S {
char c;
int i;
};
, скорее всего, займет 8 байтов на вашей платформе из-за необходимости в 3 байта заполнения после члена char
.Обратите внимание, что char
считается как 1, int
- как 4, а дополнительные 3 байта заполнения между ними составляют 8.
Обратите внимание также, что это может легко ввести зависимость окончательного размера структуры в порядке объявления членов. Например, эта структура
struct S1 {
char c1;
int i;
char c2;
};
на вашей платформе, вероятно, будет иметь размер 12, а эта
struct S2 {
int i;
char c1;
char c2;
};
будет занимать только 8 байтов. Этот последний пример предназначен для иллюстрации того, что окончательный размер структуры не может быть выражен в терминах того, сколько байтов «считает» каждый член. Отношения между участниками также важны.
Это полностью зависит от реализации, но, предположительно, если ваша система может получить доступ к любому из трех коротких
в struct, не беспокоясь о выравнивании, она может получить доступ к любому short
и, следовательно, к любому члену данных в массиве ThreeShorts
, не беспокоясь о выравнивании. Следовательно, нет необходимости более строго выравнивать конструкции.
Для примера IntAndChar
, int
предположительно имеет размер 4, а реализация связана с его выравниванием. Чтобы гарантировать, что каждый член int
в массиве IntAndChar
правильно выровнен, структура должна быть дополнена.
размер
массива T [n]
точно определяется как sizeof (T) * n
.