Автобоксинг в Джава вчера и сегодня (только для джавистов).

 
1 2 3
US Сергей-4030 #08.12.2007 02:51
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Как известно, начиная с Java 5 у нас есть автобоксинг, то есть вместо

Boolean b=new Boolean(true)

мы можем ставить просто

Boolean b=true


При этом надо заметить, что для String такое уже давно-давно, правильно? Т.е. мы пишем просто

String s="blabla"

И вот такой вот вопросик знатокам. Некоторые далекие от науки утверждают, что

String s="abc" и
Boolean b=true

совершенно эквивалентно соответственно:

String s=new String("abc") и
Boolean b=new Boolean(true)

(ну и для прочих типов то же - для int, long etc).

И, значит, вопрос такой: а точно ли это эквивалентно? :) И если не совсем эквивалентно, то в чем отличие?
 

Murkt

Pythoneer

Если я правильно помню, как это всё работает, то с помощью new новый объект будет создаваться почти всегда (исключая boolean и целые числа в диапазоне -128..127), то есть

String s = new String("abc");
String s1 = new String("abc");
s1 != s

а без new - зависит от погоды на Марсе, то есть

String s = "abc";
String s1 = "abc";
s == s1

Правда, я не уверен в том что сказал - на Джаве уже больше года ничего не писал. Я думаю, что проще просто проверить коротенькой программой.
[team Їжачки - сумні падлюки]  
+
-
edit
 

Balancer

администратор
★★★★★
Boolean - кешируется, а String - нет?

Ещё интереснее сравнить:
Integer x = 125;
Integer y = 125;
Integer z = 135;
Integer t = 135;

При этом x == y, но z != t :)
 
+
-
edit
 

Murkt

Pythoneer

Balancer> Boolean - кешируется, а String - нет?

100% кэшируется Boolean и целые числа в диапазоне -128..127.

Что мы и видим:
Balancer> Ещё интереснее сравнить:
Balancer> Integer x = 125;
Balancer> Integer y = 125;
Balancer> Integer z = 135;
Balancer> Integer t = 135;
Balancer> При этом x == y, но z != t :)

В Питоне, кстати, строки кэшируются до определённой длины. И при определённых действиях.
[team Їжачки - сумні падлюки]  
US Сергей-4030 #08.12.2007 16:41  @Murkt#08.12.2007 13:10
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Murkt> Если я правильно помню, как это всё работает, то с помощью new новый объект будет создаваться почти всегда (исключая boolean и целые числа в диапазоне -128..127), то есть
Murkt> String s = new String("abc");
Murkt> String s1 = new String("abc");
Murkt> s1 != s
Murkt> а без new - зависит от погоды на Марсе, то есть
Murkt> String s = "abc";
Murkt> String s1 = "abc";
Murkt> s == s1

Exactly. Только с помощью "new" новый объект будет создаваться просто всегда, а не почти всегда. (new Boolean(true))!=(new Boolean(true)).
 
+
-
edit
 

Mishka

модератор
★★★
Э-э-э, тут надо смотреть спецификации языка, а не имплементации. :) Если в спецификациях сказано, что

Boolean b=new Boolean(true);
Boolean b=true;

Эквивалентны, то реализаторам надо гонады откручивать. Потому как очевидны некошерные оптимизации. Но, если в языке прописано что созданный временный объект может переиспользоваться, то всё в порядке. Судя по реализации там применено такое:

Boolean b1=true;
Boolean b2=true;

Вырождается в

Boolean temp=new Boolean( true );

Boolean b1=temp;
Boolean b2=temp;
 
+
-
edit
 

Balancer

администратор
★★★★★
Mishka> Судя по реализации там применено такое:

Для Boolean я код не смотрел, а вот в Integer - именно так. Точнее, прямая проверка, если число <=127, то берём объект из кеша, если >127 - то создаём по new.

...

Я на эти грабли наступил, когда JBForth писал :) Целый вечер разбирался, почему у меня == для Integer не работает :)

...

Кстати, за это тоже отрывать что-то разработчикам надо. Всё же, сравнивать объекты по значению нужно намного чаще, чем по эквивалентности классов. Вся программа превращается в if(s1.equals(s2)) ... if(n1.equals(n2)) ...

Лучше бы наоборот, == работало для значения, а .equals() - для точной проверки эквивалентности классов.
 
+
-
edit
 
US Сергей-4030 #09.12.2007 06:41  @Mishka#09.12.2007 05:29
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Mishka> Это наследие С++ :F

Я бы сказал, наоборот. Методу equals нужна гибкость. Если бы == проверяло равенство "содержимого", то его нельзя было бы override средствами языка без костылей. В отличие от.
 
US Сергей-4030 #09.12.2007 06:48
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Хотя, конечно, костыли в Джава и так есть. Как минимум тот же readResolve. Некрасивенько. :(
 
UA Murkt #09.12.2007 10:56  @Сергей-4030#09.12.2007 06:41
+
-
edit
 

Murkt

Pythoneer

Mishka>> Это наследие С++ :F
Сергей-4030> Я бы сказал, наоборот. Методу equals нужна гибкость. Если бы == проверяло равенство "содержимого", то его нельзя было бы override средствами языка без костылей. В отличие от.
Да, почему они не сделали перегрузку операторов? Побоялись, что толпа леммингов не осилит? Классная ведь штука.
[team Їжачки - сумні падлюки]  
US Сергей-4030 #09.12.2007 11:13  @Murkt#09.12.2007 10:56
+
-
edit
 

Сергей-4030

исключающий третье
★★
админ. бан
Mishka>>> Это наследие С++ :F
Сергей-4030>> Я бы сказал, наоборот. Методу equals нужна гибкость. Если бы == проверяло равенство "содержимого", то его нельзя было бы override средствами языка без костылей. В отличие от.
Murkt> Да, почему они не сделали перегрузку операторов? Побоялись, что толпа леммингов не осилит? Классная ведь штука.

Когда начинаются разговоры про крутых и некрутых - это не ко мне, это вы сами. А почему не сделали - совершенно понятно, потому, что в общем эта штука вредная, потому, что вреда от нее куда больше, чем пользы. Те места, где ее можно применять "правильно" - раз-два и обчелся. Не стоит городить огород.

PS Даже для тех, кто почитает других леммингами. ;)
 
UA Murkt #09.12.2007 11:24  @Сергей-4030#09.12.2007 11:13
+
-
edit
 

Murkt

Pythoneer

Murkt>> Да, почему они не сделали перегрузку операторов? Побоялись, что толпа леммингов не осилит? Классная ведь штука.
Сергей-4030> Когда начинаются разговоры про крутых и некрутых - это не ко мне, это вы сами. А почему не сделали - совершенно понятно, потому, что в общем эта штука вредная, потому, что вреда от нее куда больше, чем пользы.
В том же сишарпе, который позиционируется сами знаете как, перегрузка операторов есть - и никто не жалуется, и не говорит "Фу-фу, перегрузка операторов!". Под такую аргументацию, как у тебя, можно подвести почти любую возможность языка. Я вполне понимаю, что можно нагородить при помощи перегрузки операторов, однако ведь точно так же можно нагородить и без неё.

Сергей-4030> Те места, где ее можно применять "правильно" - раз-два и обчелся. Не стоит городить огород.
Только используются эти места очень часто. Хотя бы те же "нестандартные" Numeric-типы (или они называются Number? не помню точно), типа BigInteger. Или StringBuffer/StringBuilder. В том же Питоне, в котором использование всех доступных возможностей "сделать красиво" (syntax hacking) считается тру и pythonic, перегрузка операторов используется только там, где она действительно имеет смысл. В стандартной библиотеке, в сторонних, вообще в любом коде, который я встречал - не видел ни разу чтоб перегрузка операторов использовалась в местах, в которых она выглядит неуместно.
[team Їжачки - сумні падлюки]  
US Mishka #09.12.2007 20:47  @Сергей-4030#09.12.2007 06:41
+
-
edit
 

Mishka

модератор
★★★
Mishka>> Это наследие С++ :F
Сергей-4030> Я бы сказал, наоборот. Методу equals нужна гибкость. Если бы == проверяло равенство "содержимого", то его нельзя было бы override средствами языка без костылей. В отличие от.
Не-а, это именно от С — когда всё указатели, то операция сравнения сравнивает адреса, а не содержимое.
 

Mishka

модератор
★★★
Murkt> Да, почему они не сделали перегрузку операторов? Побоялись, что толпа леммингов не осилит? Классная ведь штука.

А посмотри на эту тему Алгол 68 — там можно перегружать всё и задавать сверху приоритеты операций. Собственно, С++ эту часть оттуда и брал. Но головной боли реализаторам и пользователям добавляет неимоверно — пути поиска правильного приложение последовательности операций — это та ещё тема. С точки зрения реализаторов это связано с тем, как применять автопреобразования и возникающие из-за этого неоднозначности прохода дерева (графа) приведений типов.
 
+
-
edit
 

Balancer

администратор
★★★★★
Mishka> Не-а, это именно от С — когда всё указатели, то операция сравнения сравнивает адреса, а не содержимое.

Там всё логичнее было :) (p == q) и (*p == *q) имели вполне очевидное различие.
 
+
-
edit
 

Balancer

администратор
★★★★★
Mishka> А посмотри на эту тему Алгол 68 — там можно перегружать всё и задавать сверху приоритеты операций. Собственно, С++ эту часть оттуда и брал. Но головной боли реализаторам и пользователям добавляет неимоверно

В Хаскелле (ЕМНИП) не только операторы перегружаются и приоритеты задаются, но и новые операторы вводятся. А транслятор - очень простой, опять же, НЯЗ :)
 

Murkt

Pythoneer

Murkt>> Да, почему они не сделали перегрузку операторов? Побоялись, что толпа леммингов не осилит? Классная ведь штука.
Mishka> А посмотри на эту тему Алгол 68 — там можно перегружать всё и задавать сверху приоритеты операций.
Какие могут быть плюсы в переопределении приоритетов операций? Мы ведь переопределяем только арифметические и логические операции. Я не вижу никакой пользы в том, чтоб поменять приоритеты у сложения и умножения.

Mishka> Но головной боли реализаторам и пользователям добавляет неимоверно — пути поиска правильного приложение последовательности операций — это та ещё тема. С точки зрения реализаторов это связано с тем, как применять автопреобразования и возникающие из-за этого неоднозначности прохода дерева (графа) приведений типов.
Заметь, что негатив ты указал только для переопределения приоритетов ;)
[team Їжачки - сумні падлюки]  
+
-
edit
 

Mishka

модератор
★★★
Balancer> Там всё логичнее было :) (p == q) и (*p == *q) имели вполне очевидное различие.
Ну, так та самая * и есть isequal.
 
+
-
edit
 

Mishka

модератор
★★★
Balancer> В Хаскелле (ЕМНИП) не только операторы перегружаются и приоритеты задаются, но и новые операторы вводятся. А транслятор - очень простой, опять же, НЯЗ :)

Так в Алголе 8 и новые любой арности. И становится это слово (обозначение операции) равноправным с тем, что определено в стандарте. Надо смотреть, если Хаскел разрешает переопределять стандартные операторы для стандартных видов.
 

Mishka

модератор
★★★
Murkt> Какие могут быть плюсы в переопределении приоритетов операций? Мы ведь переопределяем только арифметические и логические операции. Я не вижу никакой пользы в том, чтоб поменять приоритеты у сложения и умножения.

Нормальные. Например, ты вводишь обобщение операции "возведение в степень". И хочешь её сделать раньше той, которая возведение в степень. Или вводишь операцию умножения двух строк. И должна она быть ниже конкатенации.

Murkt> Заметь, что негатив ты указал только для переопределения приоритетов ;)

Нет, негатив в том и что надо граф приведений вычислять и давать чёткое определение, какой из возможных путей выбрать.
 
+
-
edit
 

Balancer

администратор
★★★★★
Murkt> Какие могут быть плюсы в переопределении приоритетов операций?

^ может быть XOR, а может - возведением в степень. Приоритеты - разные :)
 
+
-
edit
 

Balancer

администратор
★★★★★
Balancer>> Там всё логичнее было :) (p == q) и (*p == *q) имели вполне очевидное различие.
Mishka> Ну, так та самая * и есть isequal.

Однако (*p == *q) намного нагляднее, чем p.equals(q) :) Вот незамутнённый разум подумает, что как раз p.equals(q) - это стравнение эквивалетности указателей, а не значений :)
 
+
-
edit
 

Murkt

Pythoneer

Murkt>> Какие могут быть плюсы в переопределении приоритетов операций?
Balancer> ^ может быть XOR, а может - возведением в степень. Приоритеты - разные :)
В одном языке он или то, или другое. Если он в одном месте XOR, а в другом - возведение в степень, то это личная мозговая травма писателя, вводить ради этой травмы другую я смысла не вижу.
[team Їжачки - сумні падлюки]  

Murkt

Pythoneer

Murkt>> Какие могут быть плюсы в переопределении приоритетов операций? Мы ведь переопределяем только арифметические и логические операции. Я не вижу никакой пользы в том, чтоб поменять приоритеты у сложения и умножения.
Mishka> Нормальные. Например, ты вводишь обобщение операции "возведение в степень". И хочешь её сделать раньше той, которая возведение в степень.
Введение новых операций в язык - это изменение синтаксиса. Если мы изменяем синтаксис, то нам, понятное дело, нужно как-то определить порядок. Но это уже в другую степь.

Mishka> Или вводишь операцию умножения двух строк. И должна она быть ниже конкатенации.
Это доведение до абсурда - во-первых, строки друг на друга не умножаются; а во-вторых умножение всегда должно быть выше приоритетом, чем сложение, чтобы не сбивать именно человека с толку. Я ведь говорю именно о возможностях для улучшения читаемости кода, а такие финты (умножение строк, например) эту самую читаемость улучшить не могут.
[team Їжачки - сумні падлюки]  
1 2 3

в начало страницы | новое
 
Поиск
Настройки
Твиттер сайта
Статистика
Рейтинг@Mail.ru