Jawa / Говнокод #12114 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
Float nan=Float.NaN;
new Float(10).compareTo(nan);
//-1
nan.compareTo(nan);
//0
new Float(Float.POSITIVE_INFINITY).compareTo(nan);
//-1. POSITIVE_INFINITY<NAN. LoL

http://ideone.com/9WIo16
Тут некоторые товарищи в соседнем треде предлагали сравнивать объекты через compareTo()==0, если возможно.
Ну и беречься от equals как от огня, если есть Comparable.
А вот к чему это приводит.

Запостил: 3.14159265 3.14159265, (Updated )

Комментарии (54) RSS

  • Говно в том, что NaN.compareTo(NaN) == 0?
    по-правильному должен всегда возвращать -1? 🙂
    Ответить
    • У compareTo() нет четвертого состояния - несравнимо. С equals() та же проблема.
      Ответить
    • А вот. Я понял.
      Давайте взглянем на это под другим углом.
      На самом деле, есть трабла поглобальней - никак нельзя быстро и красиво сравнить 2 Numbera.
      Если б они добавили всего-то одну строку в Number - implements Comparable<Number> и сделали в Number equals(x){return 0==compareTo(x);} - всё было б проще.

      Но они этого не сделали. Почему?
      http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4414323
      Ответить
      • С контравариантностью вообще нужно быть осторожным. IMHO, нужно стараться проектировать так, чтобы было T extends Comparable<T> (а не Comparable<SuperT>). Опять от наследования сплошные проблемы...
        Ответить
      • А вот кстати. Допустим они все это реализовали. И теперь у нас equals может сравнить два любых number'а. В стандартных классах можно запилить пачки кастов и сравнений для конкретных типов. А вот как быть с нестандартными классами, которые будут добавлены только потом? myNumber.equals(floatNumber) я еще до ума доведу, а вот обратное ему floatNumber.equals(myNumber) - хрен там. А некоммутативное equals() не есть гуд.
        Ответить
        • а)Можно было запретить писать своих наследников для Number.
          > а вот обратное ему floatNumber.equals(myNumber)
          б) есть как бы интерфейс. правда херовый, но идея понятная - привести всё к общему знаменателю.
          если ты херово переопределил
          public abstract double doubleValue();
          это твои проблемы

          Вот это очевидное поведение new Byte(2).equals(2) //false
          Гораздо ужасней, чем предполагаемые "свои" имплементации.
          Они такие все умные в EJ и других книжках, а в коде - говно, треш и пиздец.
          Ответить
          • > public abstract double doubleValue();
            Для длинных целых чисел это весьма хуевый интерфейс. Вот разве что свести все к Rational'ам, и окончательно забить на скорость...
            Ответить
            • Ну да. Но ведь могли уже сто раз сделать Rational. Там ниче не менялось since 1.4. Прикрутить сей интерфейс к Int,Long,Byte,Char и прочим - дело 5 минут. Double, Float - идут лесом.
              Заодно решить известные проблемы с плавающими диапазонами.

              >Для длинных целых чисел это весьма хуевый интерфейс.
              Даже если б там epsilon поставили - я был бы рад.
              >скорость
              Java. Не смешите.

              Просто им похуй.
              Ответить
          • > new Byte(2)
            Тут еще веселее. Это вообще не скомпилится.
            Ответить
            • Подумаешь. Ну не написал каст.
              Еще можно так : Byte.valueOf ( "2" ).equals(2) //false
              Byte.valueOf ( "2" ).equals("2") //wtf?
              Ответить
              • Ага. Вроде и документировано, что Byte можно сравнивать только с Byte, но вот неприятный осадок всеобщей недоделанности остается.
                Ответить
                • Срань. Нубам вбивают в голову - не пишите ==. Сравнивайте через equals(). По началу всё работаёт.
                  Потом лезет NPE. Нуб быстро запоминает - надо ставить проверку. Или стиль использовать магистра Йоды.
                  Всё работает хорошо. Более никто ничего не говорит. Правило крепко усаживается в голове.
                  А потом начинаются исключения, где ни ==, ни equals корректо не работают или надо таки сравнивать через ==
                  Ответить
                  • Самый эпичный equals все-таки у java.net.URL... Вот он рвёт все шаблоны.

                    P.S. Надо бы на ведроиде попробовать сравнить два URL'а. Интересно, выдаст ли он на эту хуиту NetworkInMainThreadException или нет.
                    Ответить
                  • Забавно. Видимо ребят из гугла заебала это джавоблядство, и они сделали вот так:

                    This problem is fixed in Android 4.0 (Ice Cream Sandwich). In that release, URLs are only equal if their host names are equal (ignoring case).
                    Ответить
        • Почти наверняка на уровне байткода можно объявить метод специализирующийся на уже существующем классе, типа как в Шарпе static Method(this foo, ...).
          Ответить
            • Хз. Я жабий байткод не знаю почти совсем, но знаю, что флешевый сваяли по аналогии, а там такое можно, если захотеть. Тут только вопрос, описаны ли эти методы как и все остальные, или они как-то специально в самой виртуальной машине хранятся.
              Ответить
              • На StackOverflow вот так пишут:
                It's not simple. Once a class is loaded by a classloader, there is no way to change the methods of loaded classes. When a class is requested, a classloader will load it and link it. And there is no way to change the linked code or to add/remove methods.
                ...
                We can't add or remove fields too.
                Ответить
                • Ну байткод изменять после загрузки - это уже как Боржоми, очень поздно...
                  Ответить
                  • Ну а правка байткода до загрузки равносильна подмене системных либ своими. Что тоже ужасно (хотя и вполне реально).

                    В жабе просто принцип: 1 класс - 1 файл. Он не нарушается даже для вложенных и анонимных классов. Поэтому подмешать какие-то методы в чужой класс без его перекомпиляции нереально.
                    Ответить
                    • Ну... тогда никак, наверное 🙂
                      Честно, я не знаю, как именно организован байткод, но скорее всего есть какое-то "квалифицированное" имя, которое определяет откуда берется метод, и каким образом он относится к тому, на чем специализируется. Если скомпилировать еще один с именем сконструированым по такому же принципу - то почему бы и не заработать? Классов же как таковых нету в байткоде, это превращается просто в имена методов каким-то образом распознаваемые рантаймом как принадлежащие тому же классу. Хз. просто нет достаточно рвения попробовать подсунуть фейк со специализацией на том же объекте, что и системый класс.
                      Ответить
                      • В .class файлах, емнип, имена методов хранятся в неквалифицированном виде. Поэтому очень маловероятно, что загрузчик пропустит метод, в котором к имени дописали левую фигню.
                        Ответить
              • > как-то специально в самой виртуальной машине
                В C# экстеншен-методы преобразуются компилятором в вызовы статических методов, скорее всего, в флеше что-то аналогичное.

                Для жабы есть AOP, но это не совсем то.
                Ответить
                • Нет, во флеше все методы (если это методы класса, т.е. с первым аргументом this) просто записываются в том же пространстве имен, что и класс, на котором специализируются. Чтобы получить ссылку на класс в this первым опкодом в функции идет OThis - и это все, что требутется для того, чтобы функция стала методом.
                  Ответить

Добавить комментарий

Из-за тебя ушел bormand, guest!

    А не использовать ли нам bbcode?


    8