Ещё одна задачка про Java internals

Рубрика: Java, Задачки | 1 December 2007, 22:36 | Vadim Voituk

Вот набрел в сети на ещё одну заковыристую задачу на знание спецификации Java
Код:
[java]

  double dd = 10.0;
  Double r = dd;
  Double r1 = dd;
  System.out.println("(r==r1) is "+(r==r1));

  Double r2 = 10.0;
  Double r3 = 10.0;
  System.out.println("(r2==r3) is "+(r2==r3));

  int ft = 21;
  Integer i1 = ft;
  Integer i2 = ft;
  System.out.println( "(i1==i2) is " + (i1==i2) );

  Integer i3 = new Integer(21);
  Integer i4 = new Integer(21);
  System.out.println("(i3 == i4) = "+(i3 == i4));

[/java]

Вопрос: что будет выведено на экран и почему?

Комментариев: 13

13 Responses to “Ещё одна задачка про Java internals”

Комментарии:

  1. Anton Naumov

    а профессиональным Java-разработчикам можно участвовать? потому что у меня ответ готов. но я не уверен, что стоит его публиковать вот так сразу :)

  2. Vadim Voituk

    Антон, конечно же можно! Даже нужно!
    Меня больше интересует не результат (его мне показали 2 магические утилиты javac & java), а пояснения к этому результату. Вот их то и хотелось бы тут прочесть.

  3. Petya

    Answer:
    (r==r1) is false
    (r2==r3) is false
    (i1==i2) is true
    (i3 == i4) = false

    Reason:
    - doubles can not be checked for equality, need to use Double.compareTo() == 0 instead
    - Integer == Integer will check if the reference is the same, rather than check if the values are the same. So the first example, the references are the same, the second example, the references are different. Need to use Integer.equals() instead.

  4. Sergey

    Расшифруйте плиз, кто-нибудь, для менее просвещенных, что это означает.

  5. Petya

    Prostite, ya kapelku chetaiu po russki, no pechatat russkim shriftom ne umeiu.

  6. Olostan

    Может кому интересно будет мою старую заметку почитать (правда там .нет, но в яве всё то же самое)
    http://dev-crossroads.blogspot.com/2007/06/interesting-code-puzzles.html

  7. Vadim Voituk

    Спасибо за ссылку – интересные задачки/нюансы.

  8. Anton Naumov

    все просто. на самом деле при сравнении объектов с использованием == сравниваются не значения, а объекты. т.е. тот единственный раз, когда было получено значение true, объекты были равны, т.е. содержали ссылки на один и тот же адрес.
    о том, почему для Double, в том же случае, результат false, лучше меня сказано в спецификации:

    Floating-point equality testing is performed in accordance with the rules of the IEEE 754 standard:

    If either operand is NaN, then the result of == is false but the result of != is true. Indeed, the test x!=x is true if and only if the value of x is NaN. (The methods Float.isNaN and Double.isNaN may also be used to test whether a value is NaN.)

    Positive zero and negative zero are considered equal. Therefore, -0.0==0.0 is true, for example.

    Otherwise, two distinct floating-point values are considered unequal by the equality operators. In particular, there is one value representing positive infinity and one value representing negative infinity; each compares equal only to itself, and each compares unequal to all other values.

  9. Anton Naumov

    а если говорить с точки зрения практики программирования, то код нужно писать правильно. а правильно означает максимально прозрачно, просто и понятно. это конечно чудная задачка на понимание языка и базовых принципов, достойна тестов на сертификацию и все такое… но на практике правила кодирования могу исключать даже конструкции типа:
    а != b ? c == d ? e : f : g
    потому как сложно для понимания, а сдедовательно является источником ошибок. и блистать знаниями при разработке приложений в продакшин никто не даст. ибо командная работа. а для понимания, почему нельзя использовать == в сравнении объектов, конечно да, хороший пример.

  10. Vadim Voituk

    Полностью согласен! И стараюсь придерживаться того же подхода.
    Гении, которые могут написать код очень элегантно, это конечно хорошо, но порою прочеть и понять этот код могут только они сами

  11. Anton Naumov

    все гениальное — просто. не случайно это именно так. элегантный код — это такой, который понятен любому программисту, функционально полный и занимает ровно столько места, сколько необходимо. иначе говоря, используя все возможности языка и опираясь на соглашения о стилистике кода, каждая написанная строчка осмысленна, функционально важна и понятна — вот это гениальный код, это элегантный код. как правило этот код рождается после нескольких итерация рефакторинга, если человек умеет писать так сразу — он воистину величайший профессионал, честь ему и хвала, мега респект и уважуха :)

    но это не относится к теме треда. чехарда с операциями == это не элегантно, это не гениальность в моем понимании, но снобизм. усложнение простых вещей, программный нигизм если хотите. и такое оправдано только в случае, если моя оценка будет эталоном для других, мое мнение будет приниматься как данность и не подвергаться сомнению другими людьми. т.е. в случае выдачи сертефиката. что и делается.

  12. Enterit

    Везде где false – понятно почему – потому что сравниваются ссылки на разные объекты.
    Там где true – это потому что при автобоксинге int объекты берутся из кеша (не помню для какого диапазона чисел). double для автобоксинга не кешируется (слишком много пришлось бы кешировать :) )

  13. Kir

    Integer i1=10;
    Integer i2=10;
    System.oun.println(i1=i2);

    =)

Leave a Reply