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

    +72

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    public static String getClassName(final HWND hWnd) {
    	final char[] cname_b = new char[1024];
    	User32.INSTANCE.GetClassName(hWnd, cname_b, 1000);
    
    	final char[] cname_b_truncated = ArrayUtils.toPrimitive(Iterables
    		.toArray(Functional.takeWhile(Arrays.asList(ArrayUtils
    			.toObject(cname_b)), Predicates.not(Predicates
    			.equalTo(Character.valueOf((char) 0)))),
    			Character.class));
    
    	return String.valueOf(cname_b_truncated);
        }

    Только что выдавил)

    Интерес представляют строки с 5 по 9. Тут должно было быть всего-лишь
    takeWhile (/= '\0') cname_b
    но из-за боксинга/анбоксинга (примитивные типы в Java не могут быть параметрами Generic), и из-за того, что массивы в Java не Iterable - получилось ЭТО.

    Запостил: burdakovd, 17 Июля 2010

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

    • Ах, да можно было сделать
      StringBuilder b = new StringBuilder();
      for(int i = 0; i < 1024 && cname_b[i] != (char)0; ++i)
      b.append(cname_b[i]);
      , но как-то это сомнительно, когда для такого рода задач есть почти стандартная функция takeWhile
      Ответить
      • стандартно это так:
        public static String getClassName(final HWND hWnd) {
        final char[] cname_b = new char[1024];
        User32.INSTANCE.GetClassName(hWnd, cname_b, cname_b.length);
        final String result = new String(b);
        return result.substring(0, result.indexOf(0));
        }
        да - и обрати внимание - теперь размер буфера указывается один раз - в его определении
        Ответить
        • Да, что я был не в себе, раз про substring забыл, так действительно четче.

          Ну и ещё что-то завтыкал, что "If the function succeeds, the return value is the number of characters copied to the specified buffer.", то есть количество символов заранее известно, тогда вообще всё упрощается.

          public static String getClassName(final HWND hWnd) {
          final char[] cname_b = new char[1024];
          final int count = User32.INSTANCE.GetClassName(hWnd, cname_b, 1000);
          return new String(cname_b, 0, count);
          }

          Что-то подсветка в камментах не работает, есть какой-то тег?
          Ответить
          • блин, уже не редактируется... ну и cname_b.length конечно
            Ответить
          • замени 1000 при вызове на cname_b.length,
            добавь при 0 == count бросание exception с информацией взятой из getLastError и будет совсем четко

            есть bbcode-подсветка - я забыл тегом оформить
            Ответить
            • Exception я планировал просто ещё не дошёл до этого, правда придётся без GetLastError() т.к. при работе через jna GetLastError() всегда возвращает ноль.

              А вот с substring всё же неприятно, что ненужные символы после \0 будут всё равно конвертироваться в строку, и только затем отбрасываться, ну и к тому же takeWhile работает в один проход (точнее даже в 0, так как он ленив), а indexof+substring в два.

              Хотя из-за всех этих конвертаций c takeWhile получается уныло.
              Ответить
    • >Только что выдавил)
      АйАйАй. Насрал и показываешь... Как не красиво...
      Ответить
      • как раз таки понимание, что это не айс, похвально. главное что бы умел переписать нормально
        Ответить
    • мля, это че, ЖНИ?
      Ответить
      • jna
        Ответить
        • на порядок лучше чем жни. раз за тя делают всю грязную работу. однако на мой взгляд, жаба должна оставаться кроссплатформенной, не надо ее притягивать туда, где больше бы подошел дотнет
          Ответить
          • Ну просто у меня серверная часть кода будет на GAE, там дотнета нет, есть Java. Вот и решил клиентскую часть тоже на Java сделать, чтобы потом проще было взаимодействие налаживать.

            По сравнению с шарпом не хватает только удобных лямбд и LINQ.
            А с вызовом Win API разницы особо нет, там вызывать через P/Invoke, тут через JNA (хотя тут это сторонняя библиотека, но работает, и даже есть уже готовые интерфейсы для User32, Kernel32 и т.д.)
            Ответить
          • А смысл ради одного лишь стыка с WinAPI прикручивать .Net? Ксати зачем сразу .Net а не просто C? :)
            Я как-то и с COM-объектами из java работал - ничего так, особых ужасов не заметил.
            Ответить
            • дотнет так же удобен в кодинге как и жаба, а вот считаю чрезмерно для нативных задач тянуть еще и жабную вм
              Ответить
              • А я думаю что чрезмерно для примитивных WinAPI-задач покупать Visual Studio.
                Ответить

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