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

    +119

    1. 1
    2. 2
    3. 3
    public static RuntimeException propagate(Throwable throwable)
    
    This method always throws an exception. The RuntimeException return type is only for client code to make Java type system happy in case a return value is required by the enclosing method.

    Давно пора сделать аннотацию типа noreturn, чтобы компилятор не ругался и подсвечивал мёртвый код.

    Запостил: someone, 25 Марта 2014

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

    • показать все, что скрытоvanished
      Ответить
    • Я тоже такой хак видел на SO. Он выносит мозг неподготовленным людям, поэтому я просто дописываю в конец метода return null;
      Ответить
    • и писать throw propagate(t);
      гуава такая гуава
      Ответить
      • Ну это, видимо, для более точного бектрейса. Чтобы гуавовские кишки в нем не показывались.
        Ответить
        • подделка стектрейса?
          Ответить
        • Кишки всё равно будут видны, стектрейс же при создании исключения создаётся, а не при выбросе.
          Ответить
          • О как. А мне казалось, что его туда вписывает throw. Ну буду знать, спасибо.
            Ответить
        • Нет, возвращаемое значение там исключительно затем, чтобы компилятор не ругался, увидев просто propagate в функции, которая должна что-то возвращать. А throw propagate он сжуёт, хотя на самом деле до этого throw дело просто не дойдёт: исключение бросается внутри функции propagate.
          Ответить
      • всё, теперь дошло, зачем это. Эта хрень по заветам \pi превращает все исключения в RuntimeException.

        У меня тут код есть, который конвертирует IOException в RuntimeException а потом выше по цепочке RuntimeException в IOException.

        олсо полезно борманду
        http://govnokod.ru/13933
        Ответить
        • Что я и предложил в первом комменте по ссылке :)
          Ответить
        • В конце-концов есть родной Thread.currentThread().stop(e);
          Ответить
          • Это некулюторно. Есть же sneakyThrow.
            Ответить
            • > Есть же sneakyThrow.
              где?
              Ответить
              • В lombok, например. А вообще идиома довольно известная, приводится в Java Puzzlers, например. Вот пример из исходников Android:

                public final class SneakyThrow {
                    private SneakyThrow() {}
                
                    public static void sneakyThrow(Throwable t) {
                        SneakyThrow.<Error>sneakyThrow2(t);
                    }
                
                    /**
                     * Exploits unsafety to throw an exception that the compiler wouldn't permit
                     * but that the runtime doesn't check. See Java Puzzlers #43.
                     */
                    @SuppressWarnings("unchecked")
                    private static <T extends Throwable> void sneakyThrow2(Throwable t) throws T {
                        throw (T) t;
                    }
                }
                Ответить
                • речь за родное
                  а трюк с кастом - известный.
                  Ответить
                • омфг. история с проверяемыми исключениями - вообще вызывает вопрос:
                  кто большие дураки - те, кто не умеет обрабатывать исключения, или те, кто кто по умолчанию всех считает дураками и защищает первых от самих себя?
                  и как закономерный результат: костыли, которые решают проблемы костылей и т.д. рекурсивно.
                  Ответить
                  • Самое интересное, когда кидается надкласс исключений и выяснить, какие именно подклассы могут кидаться, можно только читая код. IDE тут не помогает.
                    Ответить
                • >SneakyThrow.<Error>sneakyThrow2(t);
                  Что это?
                  Ответить
                  • джавовские дженерики в статиках. т.е. обманываем компилер, говоря, что t - это, вообще-то, не Throwable, а Error
                    короче, извращение на тему "как превратить checked exceptions в unchecked c последующим выбросом"
                    кстати, забавная штука произойдет, если мы не словим какой-нить серьезный чекед - вылетит же до обработки виртуалкой, а это - вылет проги либо ее зависон.
                    Ответить
    • Noreturn как-то очень коротко для аннотации, и в недемократических мусульманских, христианских и др. странах могут запретить использовать.
      Лучше @EventHorizonUnfoldsUnto({hawkinsRadiati onValue=0.0000e-100}), ну и еще пару аттрибутов придумать, чтобы за 80 символов перевалило, а то форматирование пострадает.
      Ответить
    • С noreturn жопа получается. Класс, в котором была описана функция с аннотацией noreturn могут заменить перед загрузкой на что-то, что все-таки может вернуть управление. И класслоадер этого даже не заметит.

      Т.е. надо либо переделывать класслоадер, чтобы он сверял флажок noreturn'а, как он сейчас это делает с final.
      Либо добавлять в конец веток, в которых управление не возвращают явно (т.к. они заканчиваются noreturn функцией) неявный throw new RuntimeException("Кровь-кишки-распидорасило! Функция с @noreturn вернула управление!").

      Видимо поэтому и не делают.
      Ответить
      • надо круче: чтобы обработка аннотации сама кидала исключение, и назвать это дело @kickass
        Ответить
    • Я предпочитаю делать так:
      public static <T> T  error(Throwable throwable) {...; throw ...}
      [...]
      if (someShit)
        return error(e);
      Ответить

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