1. Java / Говнокод #17197

    +79

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    public void playersListClearBlacklist() {
    	List<Player> itemsToRemove = new ArrayList<Player>();
    	for (int i = 0; i < blacklist.size(); i++) {
    		Player player = blacklist.get(i);
    		itemsToRemove.add(player);
    		DBCore.getInstance().deletePlayer(player);
    	}
    	blacklist.removeAll(itemsToRemove);
    }

    Из комерческого проекта

    Запостил: Smekalisty, 27 Ноября 2014

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

    • Оригинально. Довольно-таки затруднительно представить то, зачем нужен был этот лист.
      Ответить
    • Еще интересная особенность Ява-программистов (о, это потому что они про АДТ знают, наверное). Определить тип локальной переменной как интерфейс и тут же присвоить ей объект конкретного типа. Интересно догадывается ли компилятор что диспатчить нужно непосредственно метод массива а не выбирать нужную перегрузку из всех, кто реализуют список.
      Ответить
      • В джаве всегда single dispatch. Не важно как определена переменная.
        Ответить
        • >В джаве всегда single dispatch.
          вут? он об интерфейсе говорит. а как же полиморфизм?
          Ответить
          • Вы имеете ввиду перегрузки метода и выбор нужно сигнатуры?
            Да, тут всё от типа переменной зависит.

            А вот при вызове метода важен *объект* (все методы как-бы виртуальные) а не тип указателя на этот объект.

            В отличии, например, от с#, c++ итд
            Ответить
            • Будем размышлять как? itemsToRemove объявлен как List, предположим на секунду, что мы не знаем, какое значение у этой переменной, информации о том, что эта переменная типа List достаточно для того, чтобы выяснить, что метод get - это один из конкретных методов у AbstractList, AbstractSequentialList, ArrayList, AttributeList, CopyOnWriteArrayList, LinkedList, RoleList, RoleUnresolvedList, Stack, или Vector, ну и может кто-то еще в данном проекте заимплементил.

              Если бы мы не морочили голову компилятору и прямо так и сказали: "да не List это, а ArrayList", он бы сразу знал какой из методов надо вызвать. А так ему прийдется (возможно) отложить это решение до непосредственного вызова. Я слышал где-то, что компилятор Явы может сам сузить тип до конкретного и выбрать нужный метод еще на этапе компиляции, но не уверен в этом.
              Ответить
              • > еще на этапе компиляции
                На этапе компиляции - всяко нет. У джавы компилятор очень тупой и дословный. А вот JIT, емнип, может (если видит, что в эту переменную положили именно ArrayList и ничего другого не засунут).
                Ответить
              • Компилятор вовсе не обязан ничего тут понимать. Все методы в джаве виртуальные к сожалению. Метод вычислится в рантайме (опкод invokevirtual или как его там). А вот в рамках оптимизации он конечно может так сделать. Но я не уверен что javac обычного ораклового JDK так делает. А раз не делает то нет смысла явно писать ArrayList.

                В принципе даже и если и делает, то я не уверен что виртуальный диспатчинг это реально боттлнек джавы)) у нее полно иных боттлнеков.
                ---
                Мне кстати НЕ нравится что методы в джаве виртуальны. Это усложняет проектирование красивого наследования. Почему-то сановцы решили что это сложно-и-ненужно (как и множественное наследование , как и перегрузку операторов итд). Хорошо что в C# это не так.
                Ответить
                • Так а я разве говорю, что обязан? Было бы неплохо, если бы он мог, но не может - ну, что делать.
                  Я так же не настаиваю на том, что это сильно повлияет на производительность. Смысл в том, что в случае когда конкретный тип известен и защищен областью видимости функции, то использовать интерфейс для этого просто глупо, т.как совсем ничего не дает. Ну и в редких случаях можно наверное нарваться на таблицу с дофига методов, так что это таки отразится на производительности. Совсем недавно попадалась статья Одерски о рекордной невымышленой иерархии наследования включавшей 36 уровней, а если там еще и родственники по материнской линии были, то так и до сотни недолго добраться.
                  Ответить
                • vanished
                  Ответить
              • vanished
                Ответить
          • vanished
            Ответить
            • Да иди ты нахуй уже!
              ░░░░░░░░░▓▓▓▓▀█░░░░░░░░░░░░░
              ░░░░░░▄▀▓▓▄██████▄
              ░░░░░▄█▄█▀░░▄░▄░█▀
              ░░░░▄▀░██▄░░▀░▀░▀▄
              ░░░░▀▄░░▀░▄█▄▄░░▄█▄
              ░░░░░░▀█▄▄░░▀▀▀█▀
              ░░░░░░█░░░░░░░░▄▀▀░▐
              ░░░░▄▀░░░░░░░░▐░▄▄▀
              ░░▄▀░░░▐░░░░░█▄▀░▐
              ░░█░░░▐░░░░░░░░▄░█
              ░░░█▄░░▀▄░░░░▄▀▐░█
              ░░░█▐▀▀▀░▀▀▀▀░░▐░█
              ░░▐█▐▄░░▀░░░░░░▐░█▄▄
              ░░░▀▀░░░░░░░░░░▐▄▄▄▀
              Ответить
      • > диспатчить нужно непосредственно метод массива а не выбирать нужную перегрузку из всех, кто реализуют список
        Вроде бы jit умел в таких случаях делать невиртуальный вызов метода конкретного класса.
        Ответить
    • Что здесь происходит? Ебучий Костыль вместо list.clear()?
      Ответить
      • Ну да. + вызов DBCore.getInstance().deletePlayer(player ); на каждый элемент списка.
        Ответить
      • vanished
        Ответить
        • Тези церемонии са лишени от каквато и да е възвишеност. Това са всъщност дни за развлечение и нерядко може да се види коленичил вярващ да се старае да заглуши крякането на петела за борба, скрит под сарапето му. И всичко това става в светия божи храм.
          Ответить

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