59

これはおそらく非常に素朴な質問です。

ThrowableJava の a には常にスタック トレースが含まれていると信じていました。それが正しいか?

これで、スタック トレースなしで例外をキャッチできるようになりました。それは理にかなっていますか?スタック トレースなしで例外をキャッチすることは可能ですか?

4

5 に答える 5

32

Java 6 の場合:

Java 6 にはコンストラクターがないため、Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)以下の手法を使用してスタックトレースの塗りつぶしを抑制することができます (Scala から借用、How slow are Java exceptions?から知りました) 。

class NoStackTraceRuntimeException extends RuntimeException {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

使い方は同じです: throw new NoStackTraceRuntimeException ()、またはサブタイプです。

を拡張して同じことを行うこともできますThrowable

class NoStackTraceThrowable extends Throwable {
    @Override
    public synchronized Throwable fillInStackTrace() {
        return this;
    }
}

ただし、これは のサブタイプではないため、catchこれらの例外を使用できなくなり、代わりにサブタイプをキャッチする必要があります。ExceptionExceptionNoStackTraceThrowable

更新: さまざまなユースケースでのパフォーマンスに関する興味深い統計については、このSO の質問を確認してください

于 2014-08-15T09:54:40.513 に答える
7

例外でスタックトレースを抑制する最も簡単な方法は、

throwable.setStackTrace(new StackTraceElement[0]);

例外に原因がある場合は、同じことを再帰的に行う必要がある場合があります。

これにより、コストのかかるスタック トレースの作成も可能な限り削減されます。

スロー可能オブジェクトのスタック トレースは、

Throwable#fillInStackTrace()

、これは任意のコンストラクターによって呼び出されるため、回避できません。スタックトレースが実際に使用されると、StackTraceElement[] が遅延して構築されます。

Throwable#getOurStackTrace()

これは、Throwable.stackTrace フィールドがまだ設定されていない場合にのみ発生します。

スタックトレースを null 以外の値に設定すると、Throwable#getOurStackTrace() での StackTraceElement[] の構築が回避され、パフォーマンスの低下が可能な限り軽減されます。

于 2016-10-14T13:50:46.087 に答える
2

NG. の返信で示唆されているように、最初はスタック トレースが表示されているが、同じ例外で表示されなくなる場合は、JVM 最適化の影響が見られる可能性が最も高いです。その場合、次の質問は非常に似ています。

スタック トレースなしで繰り返し発生する例外 - リセットする方法は?

StackTrace を使用しない Java の NullPointerException

この JVM 機能をオフにすることもできますが、有効にしたままにして、最初からエラーを防止するか、キャッチしてより適切に処理することをお勧めします。

于 2020-03-06T07:22:36.933 に答える