Пару слов о Джаве

У ДиБРа увидел прекрасное. Как вы думаете, что выведет следующий код:
public class Main {
    public static void main(String[] args) {
        Integer a = 10, b = 10; 
        Integer c = 150, d = 150;
        System.out.println(a == b);
        System.out.println(c == d);
    }
}
Как ни странно, но «true» и «false». Насколько я понял по комментариям, это происходит из-за того, в Джаве экземпляры Integer (видимо для скорости) в диапазоне [-128; 127] предопределены. Поэтому объекты «a» и «b» равны (ссылаются на один объект), а «c» и «d» нет. А на равенство значений надо проверять вызовом метода «equals».
21 апреля 2012 17:23

dinoel (инкогнито)
21 апреля 2012, 17:37

Представляю сколько часов потрачено на поиски и исправления багов связаных с таким поведением ...

Svan (инкогнито)
21 апреля 2012, 17:42

В связи с этим вспомнился, почему–то, недавний наезд на PHP...

Александр Бабаев (bealex.moikrug.ru)
21 апреля 2012, 17:46

Есть замечательная книжка, называется Java Puzzlers http://www.javapuzzlers.com. Там сотня глав, попадается очень забавное.

Александр Бабаев (bealex.moikrug.ru)
21 апреля 2012, 17:48

Ну, и сама концепция, object interning, много где используется. :)

bolk (bolknote.ru)
21 апреля 2012, 18:02, ответ предназначен Александр Бабаев (bealex.moikrug.ru):

Процитируй что-нибудь :)

Александр Бабаев (bealex.moikrug.ru)
21 апреля 2012, 18:18

Там исходники доступны, вот несколько понятных, если интересно, расскажу, что получается:

System.out.print("H" + "a");
System.out.print('H' + 'a');
-- 1.
System.out.println((int) (char) (byte) -1);
-- 2.
int j = 0;
for (int i = 0; i < 100; i++)
  j = j++;

System.out.println(j);
-- 3.
int i = 0;
while (i == i + 1) { }
--

Это простые, там есть и с многопоточностью, с классами, со стандартной библиотекой... Не могу найти с тернарным оператором, там неявное приведение типов забавное.

Fulcrum (fulc.ru)
21 апреля 2012, 20:41

"как ни странно"

bolk (bolknote.ru)
21 апреля 2012, 20:43, ответ предназначен Александр Бабаев (bealex.moikrug.ru):

Интересно, конечно!

bolk (bolknote.ru)
21 апреля 2012, 20:44, ответ предназначен Fulcrum (fulc.ru):

Спасибо!

Александр Бабаев (bealex.moikrug.ru)
21 апреля 2012, 21:47

Лучше, конечно, книжку прочитать, часть из вещей общеполезна :) А тут примерно так:
1. 'H' + 'a' — сложение двух чисел, "H" + "a" — сложение двух строк.
2. (int) (char) (byte) -1 = 65535 что-ли, так как char — беззнаковый тип (единственный в Java), а остальные — со знаком.
3. j = 0, особенность работы с постинкрементом и присваиванием (оно раскрывается в int tmp = j; j = j + 1; j = tmp;). Там еще куча с инкрементами есть, все не упомню :)
4. вполне очевидно, что цикл быстро закончится. Но если правильно объявить i (не "int i = 0", а "double i = Double.POSITIVE_INFINITY"), то цикл превратится в бесконечный.

Eyeless (инкогнито)
21 апреля 2012, 21:52

Ну дык объект и примитив разные вещи. Хочешь арифметику - пользуй примитивы, хочешь ООП - объекты. Мешаешь вместе - ССЗБ.

bolk (bolknote.ru)
21 апреля 2012, 22:06, ответ предназначен Eyeless

Вот «Пайтон» мне нравится тем, что там нет примитивов.

Илья Ермолов (twitter.com/iErmolov) (инкогнито)
21 апреля 2012, 22:54, ответ предназначен bolk (bolknote.ru):

Из секретных источников (на самом деле на JavaOne рассказали) стало известно, что в 9-й или 10-й джаве тоже не будет примитивов. Но вот это поведение вряд ли изменится в силу того, что у джавы должна быть обратная совместимость. Ещё есть кэш строковых констант, кстати.

Александр Бабаев (bealex.moikrug.ru)
22 апреля 2012, 00:47, ответ предназначен Илье Ермолову (twitter.com/iErmolov)

Ну, интернирование статических строк есть вообще почти везде.

PastorGL (инкогнито)
22 апреля 2012, 22:54

Это JAVAAAAAAA!!!111

А если серьёзно, то пару раз нарвавшись на подобные вещи, быстро привыкаешь смотреть в исходники стандартных пакетов. У санок-то оно ещё ничего, а в айбиэмовской жабе местами такие чудеса попадаются, что просто диву даёшься, как *такое* вообще ухитряется работать в mission critical appliances...

bolk (bolknote.ru)
23 апреля 2012, 07:18, ответ предназначен PastorGL

Ну, это не только в Джаве же такое есть. Например, у Пайтона тоже может оказаться, что ID двух разных (с точки зрения программиста) объектов — одно и то же. Но операция сравнения значений в языке — два равно, что всё-таки более интуитивно.

http://desh.su (инкогнито)
23 апреля 2012, 15:23, ответ предназначен bolk (bolknote.ru):

В CPython, кстати, тоже статически выделена память для маленьких чисел (у меня в 2.7 это диапазон [-5, 256]).
А в Jython подобный диапазон [-100, 899].

Работает подобный пример, только, естественно, с оператором "is" вместо "==".

В том же духе в CPython, например, переиспользуются строки, встречаемые в коде (имена классов, методов, переменных, ключевые слова, etc).

stafi (инкогнито)
29 апреля 2012, 11:54

для сравнения объектов необходимо использовать метод equals, читайте букварь

bolk (bolknote.ru)
1 мая 2012, 10:47, ответ предназначен stafi

Вы до конца-то мой пост прочитали? Или только букварь умеете читать?

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)