java == оператор

Възможен дубликат:
Weird Java Boxing

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)


Причината, поради която второто отпечатване се оценява като true, е, че първите 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, всеки, който използва == за сравняване на стойности на който и да е Object, иска да бъде изгорен. - person Justin Ardini; 18.08.2010
comment
О, но ние сме толкова умни с String interning и == и... надушвам дим. - person Amir Afghani; 18.08.2010
comment
Това се отнася само за обекти в автоматична кутия, а не за изрично създадени. - person malejpavouk; 27.12.2010

Вие сравнявате два обекта Integer, които с помощта на оператора == сравняват двете препратки, вместо двете стойности.

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

person Jose Diaz    schedule 17.08.2010
comment
какво е 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) са стойностни типове. (забележка: може ли някой да ме уведоми, ако използвам неправилно „тип стойност“? Имам чувството, че съм.) Следното ще се отпечата вярно:

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