Как работают операторы? = И == для целых чисел в Java?
Следующий код казался мне очень запутанным, так как он предоставил два разных выхода. Код был протестирован на jdk 1.7.
public class NotEq {
public static void main(String[] args) {
ver1();
System.out.println();
ver2();
}
public static void ver1() {
Integer a = 128;
Integer b = 128;
if (a == b) {
System.out.println("Equal Object");
}
if (a != b) {
System.out.println("Different objects");
}
if (a.equals(b)) {
System.out.println("Meaningfully equal.");
}
}
public static void ver2() {
Integer i1 = 127;
Integer i2 = 127;
if (i1 == i2) {
System.out.println("Equal Object");
}
if (i1 != i2){
System.out.println("Different objects");
}
if (i1.equals(i2)){
System.out.println("Meaningfully equal");
}
}
}
Вывод:
[вывод ver1]
Различные объекты
Смысл равен.
[вывод ver2]
Равный объект
Значительно равный
Почему проверка == и!= дает разные результаты для ver1() и ver2() для того же числа, что намного меньше Integer.MAX_VALUE? Можно ли сделать вывод, что == проверка чисел более 127 (для классов-оболочек, таких как Integer, как показано в коде) является пустой тратой времени?
Ответы
Ответ 1
Целые элементы кэшируются для значений от -128 до 127, поэтому Integer i = 127
всегда будет возвращать одну и ту же ссылку. Integer j = 128
не обязательно сделает это. Затем вам нужно будет использовать equals
для проверки равенства базового int
.
Это часть Спецификация языка Java:
Если значение p в боксе равно true, false, байту или char в диапазоне от \u0000 до\u007f или int или коротком числе между -128 и 127 (включительно), тогда пусть r1 и r2 - результаты любых двух бокс-преобразований p. Всегда бывает, что r1 == r2.
Но 2 вызова Integer j = 128
могут возвращать одну и ту же ссылку (не гарантируется):
Менее ограниченные памятью реализации могут, например, кэшировать все char и короткие значения, а также значения int и long в диапазоне от -32K до + 32K.
Ответ 2
Поскольку маленькие целые числа интернированы на Java, и вы пытались использовать числа с разных сторон предела "малости".
Ответ 3
Существует кеш объектов Integer с -128 и до 127 по умолчанию. Верхняя граница может быть настроена. Верхнюю границу кэша можно контролировать с помощью опции VM -XX:AutoBoxCacheMax=<size>
Этот кеш используется при использовании формы:
Integer i1 = 127;
или
Integer i1 = Integer.valueOf(127);
Но когда вы используете
Integer i1 = new Integer(127);
то вам гарантированно получить новый объект, который не был сохранен. В последнем случае обе версии распечатывают те же результаты. Использование кешированных версий может отличаться.
Ответ 4
https://www.owasp.org/index.php/Java_gotchas
Я получил эту ссылку от одного из моих профессоров, довольно информативный.
Ответ 5
Java кэширует целые числа от -128 до 127. Поэтому объекты ARE одинаковы.
Ответ 6
Я думаю, что операторы == и!= при работе с примитивами будут работать так, как вы их используете, но с объектами (Integer vs. int) вы захотите выполнить тестирование с помощью метода .equals().
Я не уверен в этом, но с объектами == будет проверяться, является ли один объект одним и тем же объектом или нет, а .equals() будет выполнять тестирование того, что эти два объекта содержат эквивалентность по значению (или метод будет необходимо создать/переопределить) для пользовательских объектов.