0

ここでは、エラーから回復することは不可能であると述べています。例外と同じようにエラーをキャッチできるため、それが何を意味するのかわかりません。例えば:

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

上記のプログラムは正常に実行され、エラーから回復できたようです。誰でも助けることができますか?

アップデート:

スタックオーバーフローの例は少し不可解です。スタックオーバーフローから回復したいのはばかだけです。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 が表示され、手動でメモリを解放すると、プログラムは引き続き実行されます。挿入 -> OutOfMemoryError -> 解放 -> 挿入... プログラムが OutOfMemoryError から回復しました。ではない?そして意味があると思います。それで、なぜ誰かがまだプログラムが OutOfMemoryError から回復できないと言ったのか。

4

3 に答える 3

3

明らかに、例外を「キャッチ」できるからといって、(常に...)例外から回復」できるとは限りません...

...つまり、「まるで『そんな不都合な出来事』が最初からなかったかのように、まったく無傷で   出撃すること」。

原作者の要点は多かれ少なかれ、タイタニック号の哀れな魂が沈んでいるという事実を「捉えた」かもしれないが、 「回復」するためにできることは何もなかったと思う.船を無傷でニューヨークに向けて航行します。

---編集: 「さて、もう 1 つ考えさせてください!」(他の Answerer もここで行っているように。)場合によっては、catch ブロックで意図的に囲まれたコード ブロックで エラー例外が意図的に「スロー」されることがあります。

エラー(それ自体が「オブジェクト」)は、キャッチャーが認識する特定のユーザー定義型である可能性があります。(彼は、認識できないものを「再スロー」するか、単にキャッチを拒否することができます。)これは、「ルールの例外」を処理するための非常にエレガントで効率的な方法です。(だから名前が…)

コードのブロックが「ブルー ムーンに 1 回しか発生しないが、実際に発生した」状況に遭遇するたびに、最も近くにいるキャッチャー例外をキャッチすることがわかっているため、例外を空中高く投げることができます。次に、このキャッチャーは、野球のミットに着地したばかりのものを認識し、それに応じて反応することができます. さまざまなものを探している「キャッチャー」はいくつでも存在する可能性があります。

この戦略は「エラー」ではなく、プログラム内の意図的な代替制御フローです。

于 2016-07-15T03:40:04.613 に答える
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 を返し続けた場合に続行しようとするようなコードを本番環境に持ちたいと思いますか?

于 2016-07-15T03:28:11.410 に答える
0

Throwableエラーになる前に、ここでキャッチしているだけです。エラーと例外Throwableの両方のスーパークラスです。したがって、Throwable はエラー自体に匹敵するものではなく、ましてや StackOverflowError に相当するものではなく、プログラムはエラーから回復していません。

例外は軽犯罪のようなものです。あなたに、またはあなたのプログラムに起こるのは素晴らしいことではありませんが、長期間刑務所に入れられることは絶対にありません。ただし、エラーは危険です。この類推を続けると、重罪のレベルになります。Java は、たとえば C よりも安全であると考えられています。なぜなら、安全でないことをしているときはそれを教えてくれるからです。一方、C では、たとえば、配列の範囲を超えたデータにアクセスできるようになり、その方法でデバッグするのが非常に困難なひどいバグが発生します。

犯罪への類推はその時点で終わります。リンク先のページをもう少し下にスクロールすると、例外とエラーが異なる理由、つまり「アプリケーションが実行されている環境によってエラーが発生する」という理由が引き続き説明されているため、アプリケーションは実際の環境ではなく、自分自身だけを担当しているため、エラーから自発的に回復することはできません。

このページには、OutOfMemoryError の例も示されています。プログラマーは、コードをできる限り効率的にすることで OutOfMemoryError を防止することを前もって計画できますが、たとえば、 1 バイトの RAM。エラーは (ほとんどの場合) アプリケーション自体の手の届かないところにあるため、キャッチできません。Michael Markidis の例のようBad recursionに、エラーを発生させず、プログラムをクラッシュさせるエラーの原因となるプログラミング手法 (" " の使用など) を回避するのは、プログラマ次第です。

于 2016-07-15T03:37:55.067 に答える