说"它是不可能从错误中恢复的"在java?

时间:2016-07-15 03:16:57

标签: java exception out-of-memory stack-overflow unchecked-exception

Here说无法从错误中恢复过来。 我不确定它是什么意思,因为我可以像Exception一样捕获Error。 例如:

int

上述程序正常执行,似乎可以从错误中恢复。有人可以帮忙吗?

UPDATE:

stackoverflow的例子有点令人费解,只有白痴想要从stackoverflow中恢复。这是关于OutOfMemory的另一个例子:

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

它是一个简单的HashMap缓存,使用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"); } } } } 执行代码,我们很快就会看到OutOfMemoryError,然后手动释放内存,程序将继续执行。嵌件&GT; OutOfMemoryError - &gt;发布 - &gt;插入... 看到?该程序已从OutOfMemoryError中恢复。不是吗?而且我觉得它很有意义。那么,为什么还有人说程序无法从OutOfMemoryError中恢复。

3 个答案:

答案 0 :(得分:3)

显然,仅仅“捕获”异常的能力并不意味着你(总是......)能够恢复它......

... 即:“向前冲,完全毫发无损,好像'这样一个不方便的事件'从未发生过。”

我认为原作者的基本观点或多或少:即使<泰坦尼克号上的可怜人可能“抓住”事实他们的船正在沉没,他们无法做任何事情来<强力>“恢复”这艘船,并毫发无伤地驶向纽约。

--- 编辑: “现在,让我再添加一个想法!” (正如其他Answerers也在这里所做的那样。)有时,错误异常是故意“抛出”某些故意代码块被一个捕获区包围。

错误(它本身就是“对象”)可能是捕手将识别的特定用户定义类型。 (他可以“重新抛出”任何他不认识的东西,或者只是拒绝接受它。)这可以是一种非常优雅和有效的方式来处理,“例外遵守规则。“ (因此名称......)

每当一段代码遇到“只在蓝色的月亮中发生过一次,但它刚刚发生过一次”的情况时,它会向空中抛出异常,因为知道最近的捕手 抓住它。反过来,这个接球手可以识别刚落入他的棒球手套的东西,并做出相应的反应。可以有任意数量的“捕手”,寻找不同的东西。

此策略“错误”,而是程序中故意备用控制流。

答案 1 :(得分:1)

考虑以下代码实际抛出StackOverflowError

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()怎么办?如果方法一直给出StackOverflowError,你会希望在生产中有这样的代码试图继续吗?

答案 2 :(得分:0)

你只是在Throwable抓住Throwable,然后才能发现错误。 Bad recursion错误和例外 的超类。因此,Throwable不能与错误本身相比,更不用说StackOverflowError,并且您的程序没有从错误中恢复。

例外有点像轻罪指控。这不是一件很棒的事情发生在你身上,或者更确切地说,是你的计划,但它绝对不会让你长时间入狱。然而,一个错误是危险的 - 它是在重罪的水平,继续这个类比。 Java被认为比C更安全,因为它会告诉你何时做一些不安全的事情。另一方面,C允许您访问超出数组范围的数据,例如,您将获得非常难以以这种方式进行调试的错误。

在此之后,对犯罪的类比结束了。如果你进一步向下滚动on the page that you linked to,它会继续描述异常和错误不同的原因,即错误是由运行应用程序的环境引起的< / EM>,&#34;因此,因为你的应用程序只是自己负责,而不是实际的环境,它不能自己从错误中恢复。

该页面还给出了OutOfMemoryError的示例。虽然作为程序员,您可以提前计划尝试通过使代码尽可能高效来防止OutOfMemoryError,但如果代码在具有的代码上运行,则无法阻止此类错误,比方说,1个字节的RAM。无法捕获错误,因为它们(大部分)不受应用程序本身的影响。程序员(例如在Michael Markidis' example中)不会导致错误并避免任何导致错误的编程技术(例如使用&#34; import pandas as pd import numpy as np xls = pd.ExcelFile('/python_sample_data.xlsx') #Read all Excel #xls.sheet_names # Read all sheet names df_config = xls.parse('Config')#Read config data df_input = xls.parse('Data') #Read Input Data df_ss_arts = xls.parse('arts_scale') #Read individual scoring scales df_ss_music = xls.parse('music_scale') #Read individual scoring scales df_ss_vocal = xls.parse('vocal_scale') #Read individual scoring scales # Scoring categorical variables #parameters- list, df_config, df_input list = ['arts', 'music','vocal'] for i in list: #Set the ref scale exec "{0}_refscale = df_config.loc[df_config.subjectid == '{0}', 'refscale'].tolist()".format(i) #Set the ref score exec "{0}_refscore = df_config.loc[df_config.subjectid == '{0}', 'refscore'].tolist()".format(i) #Read the refscale and ref score to dict exec "di_ss_{0} = df_ss_{0}.set_index(str({0}_refscale[0].split('.')[1]))[str({0}_refscore[0].split('.')[1])].to_dict()".format(i) #Apply the mapping on a cat.variable exec "df_input['{0}'+'_score'] = df_input['{0}'].map(eval('di_ss_'+'{0}'))".format(i) #Imputation -Handling Nulls exec "imp_null_{0} = df_config.loc[df_config.subjectid == '{0}','imputation_nulls_miss'].tolist()[0]".format(i) exec "df_input.loc[df_input['{0}'].isnull() , '{0}_score'] = imp_null_{0}".format(i) #Imputation-Handling Invalids exec "imp_inv_{0} = df_config.loc[df_config.subjectid == '{0}','imputation_invalid'].tolist()[0]".format(i) exec "df_input.loc[df_input['{0}_score'].isnull() , '{0}_score'] = imp_inv_{0}".format(i) # Scoring cont. variables list = ['maths','science','social'] for i in list: exec "{0}_bin = df_config.loc[df_config.subjectid == '{0}', 'refscale'].tolist()[0]".format(i) exec "{0}_bin_score = df_config.loc[df_config.subjectid == '{0}', 'refscore'].tolist()[0]".format(i) exec "df_input['{0}'+'_score'] = pd.cut(df_input['{0}'], eval({0}_bin), labels = eval({0}_bin_score))".format(i) &#34;)这将使你的程序崩溃。