java == operator

Возможный дубликат:
странный Java-бокс

Hi,

Может кто-нибудь объяснить, почему последний отпечаток возвращает false?

int a = 100;
int b = 100;

System.out.println(a == b); // prints true

Integer aa = 100;
Integer bb = 100;

System.out.println(aa == bb); // prints true

Integer aaa = 1000;
Integer bbb = 1000;

System.out.println(aaa == bbb); // prints false

Спасибо Майкл


person Michael Ellick Ang    schedule 17.08.2010    source источник
comment
дубликат: stackoverflow.com/questions/3130311/weird-java-boxing   -  person Progman    schedule 18.08.2010
comment
Да, это многократный обман. Также stackoverflow.com/questions/3131136/ , stackoverflow.com/questions/1514910/   -  person Justin Ardini    schedule 18.08.2010


Ответы (6)


Причина, по которой вторая печать оценивается как истинная, заключается в том, что первые 128 объектов Integer кэшируются классом Integer. Вы хотите использовать .equals

person Amir Afghani    schedule 17.08.2010
comment
Да, это правильный ответ. См. Также: owasp.org/index.php/Java_gotchas Неизменяемые объекты / Класс-оболочка Кеширование - person Andy White; 18.08.2010
comment
Вероятно, это моя особенность Java, которую мне не нравится больше всего. Поговорим о несоответствиях. - person Zachary Wright; 18.08.2010
comment
Я бы очень хотел иметь возможность явно отключить автобокс инициализации. - person Thorbjørn Ravn Andersen; 18.08.2010
comment
Я подозреваю, что они сделали это ради производительности. Если вы продолжите использовать valueOf, вас не укусит, но я согласен, что это непоследовательно. - person Amir Afghani; 18.08.2010
comment
IMO, любой, кто использует == для сравнения значений any Object, просит обжечься. - person Justin Ardini; 18.08.2010
comment
О, но мы такие умные с интернированием строк и == и ... я чувствую запах дыма. - person Amir Afghani; 18.08.2010
comment
Это относится только к автоматически запакованным объектам, а не к явно созданным. - person malejpavouk; 27.12.2010

Вы сравниваете два объекта Integer, которые с помощью оператора == сравнивают две ссылки вместо двух значений.

Используйте метод equals(), чтобы убедиться, что вы сравниваете оба значения.

person Jose Diaz    schedule 17.08.2010
comment
что abput System.out.println(aa == bb); - person Anycorn; 17.08.2010
comment
-1, поскольку aa == bb выводит true. - person Tushar Tarkas; 18.08.2010
comment
+1, потому что это все правильно, даже если это не объясняет полностью. - person Justin Ardini; 18.08.2010

Вы должны использовать Integer.compareTo для проверки числового равенства для Integer объектов. Оператор == сравнивает объекты, а не числа.

person bshields    schedule 17.08.2010
comment
Вы также можете использовать Integer.equals. - person Yishai; 18.08.2010

Объекты Integer автоматически упаковываются с помощью метода Integer.valueOf(int). Взгляните на документацию по этому методу. Тогда все должно проясниться.

person Roland Illig    schedule 17.08.2010

Вы хотите использовать aaa.equals(bbb). В Java при использовании == для объектов сравнивается, являются ли они одним и тем же экземпляром объекта, а не равны ли они в соответствии с их equals() методом.

person dave    schedule 17.08.2010

Я удивлен вторым случаем возврата true. Но именно поэтому в Java Puzzlers не рекомендуется смешивать использование классов Wrapper и оператора ==.

Взгляните на этот класс и код:

public class RichardInt {
    private int value;
    public RichardInt(int value) {
        this.value = value;
    }
}

Что будет в результате следующего?

RichardInt aa = new RichardInt(100);
RichardInt bb = new RichardInt(100);
System.out.println(aa == bb); // prints false

Он печатает false, потому что оператор равенства == сравнивает ссылки при использовании с объектами. Помните, что в Java объекты являются ссылочными типами, а примитивы (например, int) являются типами значений. (примечание: может ли кто-нибудь сообщить мне, если я неправильно использую «тип значения»? У меня такое ощущение.) Следующее будет выводить true:

RichardInt aa = new RichardInt(100);
RichardInt bb = aa;
System.out.println(aa == bb); // prints true

... поскольку aa и bb ссылаются на один и тот же экземпляр RichardInt.

Так что, возможно, описанное выше поведение легче понять в следующем примере ...

Intger aaa = new Intger(1000);
Intger bbb = new Integer(1000);
System.out.println(aaa == bbb); // prints false

В более поздних версиях Java классы-оболочки (Integer, Float и Boolean и т. Д.) Могут автоматически упаковываться, что означает, что вы можете делать следующее:

Integer aa = 1000;
// this is a shorthand for...
// Integer aa = new Integer(1000);

Но когда вы пробуете что-то вроде этого, это приводит к запутанному поведению:

Integer aaa = 1000;
Integer bbb = 1000;
System.out.println(aaa == bbb); // prints false

Или, что еще лучше, у вас может получиться такая головоломка ...

// what values of x and y will result in output?
if(!(x<y)&&!(x>y)&&!(x==y)) {
    System.out.println("How is this possible?");
}

В конце концов, при работе с объектами вы захотите использовать .equals() вместо ==.

Integer aaa = 1000;
Integer bbb = 1000;
System.out.println(aaa.equals(bbb)); // prints true
person Richard JP Le Guen    schedule 17.08.2010