Что это значит, говоря "невозможно восстановить после ошибок" в Java?

Здесь говорится, что невозможно исправить ошибки. Я не уверен, что это значит, потому что я могу поймать ошибку, как исключение. Например:

public static void main(String args[]) {
    while (true) {
        try {
            throw new StackruError("stackru");
        } catch (Throwable throwable) {
            //do something
        }
        //program recover and continue to execute
    }
}

Вышеуказанная программа выполняется нормально, и кажется, что можно исправить ошибки. Кто-нибудь может помочь?

ОБНОВИТЬ:

Пример stackru немного озадачивает, только идиот хочет восстановиться из stackru. Вот еще один пример об OutOfMemory:

public class Main {
    public static Map<Long, Object> cache = null;
    public static void main(String args[]){
        while(true){
            try {
                if(cache == null) {
                    cache = new HashMap<>();
                }
                for (long i = 0; i < Long.MAX_VALUE; ++i) {
                    cache.put(i, i);
                }
            }catch(OutOfMemoryError error) {
                cache.clear();//delete some unused entry or clear all.
                cache = null;
                System.gc();
                System.out.println("release memory");
            }
        }
    }
} 

Это простой кеш HashMap, выполните код, используя java -Xmx1m Main, и мы скоро увидим ошибку OutOfMemoryError, затем освободим память вручную, и программа продолжит выполнение. insert-> OutOfMemoryError -> release -> insert... Видите? программа восстановлена ​​из ошибки OutOfMemoryError. Не так ли? И я думаю, что это имеет смысл. Итак, почему кто-то еще сказал, что программа не может восстановиться после OutOfMemoryError.

3 ответа

Очевидно, что простая способность "поймать" исключение не означает, что вы (всегда...) сможете "оправиться" от него…

... то есть: "чтобы выскочить вперед, совершенно невредимым, как если бы" такого неудобного события "никогда не происходило".

Я думаю, что основной смысл первоначального автора более или менее таков: хотя бедные души на Титанике могли "поймать" тот факт, что их корабль тонул, они ничего не могли сделать, чтобы "выздороветь". корабль и плыть на нем невредимым в Нью-Йорк.

--- Редактировать:"Теперь позвольте мне добавить еще одну мысль!" (Как и другие Ответчики также сделали здесь.) Иногда Исключение ошибки намеренно "выбрасывается" в некоторый блок кода, который намеренно был окружен блоком catch.

Может быть, ошибка (которая сама по себе является "объектом") имеет определенный пользовательский тип, который распознает ловушка. (Он может "перебрасывать" все, что он не распознает, или просто отказываться от него.) Это может быть очень элегантным и эффективным способом обработки, ну, в общем, "исключений из правила". (Отсюда и название...)

Всякий раз, когда блок кода сталкивается с ситуацией, которая "случается только один раз в голубой луне, но она только что произошла", он может выбросить исключение высоко в воздух, зная, что ближайший ловец поймает его. Этот ловец, в свою очередь, может распознать вещь, которая только что приземлилась в его бейсбольную перчатку, и ответить соответственно. Там может быть любое количество "ловцов", ищущих разные вещи.

Эта стратегия не является "ошибкой", а представляет собой намеренный альтернативный поток управления в рамках программы.

Рассмотрим следующий код, который на самом деле StackruError

public class Code
{
    public static void main(String[] args)
    {
        try
        {
            f();
        }
        catch (Throwable t)
        {               
            System.out.println("OK I'm recovered, let me try that again");

            try
            {
                f();
            }
            catch (Throwable t2)
            {
                System.out.println("What's going on here??");

                // let me try one more time.. 
                try
                {
                   f();
                }
                catch (Throwable t3)
                {
                     System.out.println("Why can't I really recover");
                }
            }
        }

    }

    // Bad recursion...
    private static void f()
    {
        f();
    }
}

Вы действительно хотите продолжить выполнение, зная, что в вашем коде есть такая проблема? Что делать, если вам нужно позвонить f() опять где-то вниз по линии? Вы хотели бы иметь такой код в производстве, который пытается продолжить, если метод продолжает давать StackruError?

Ты просто ловишь Throwable здесь, прежде чем он когда-либо доходит до точки, где это ошибка. Throwable это суперкласс ошибок и исключений. Следовательно, Throwable не сравним с самой ошибкой, тем более с StackruError, и ваша программа не восстанавливается после ошибки.

Исключение вроде обвинения в проступке. Это не фантастическая вещь, которая случается с вами, или, скорее, с вашей программой, но она определенно не посадит вас в тюрьму на длительное время. Однако ошибка опасна - продолжать эту аналогию на уровне уголовного преступления. Java считается безопаснее, чем, скажем, C, потому что она скажет вам, когда вы делаете что-то небезопасное. C, с другой стороны, позволит вам получить доступ к данным, выходящим за рамки массива, например, и вы получите ужасные ошибки, которые очень сложно отладить таким образом.

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

На странице также приведен пример ошибки OutOfMemoryError. Хотя вы, как программист, можете планировать заранее, чтобы попытаться предотвратить ошибку OutOfMemoryError, сделав свой код настолько эффективным, насколько это возможно, вы не сможете предотвратить такую ​​ошибку, если код выполняется на машине, которая имеет, скажем, 1 байт оперативной памяти. Ошибки не могут быть обнаружены, потому что они (в основном) находятся в руках самого приложения. Программист, такой как в примере Майкла Маркидиса, должен сам не вызывать ошибку и избегать любых вызывающих ошибки техник программирования (таких как использование "Bad recursion") это приведет к краху вашей программы.

Другие вопросы по тегам