web-dev-qa-db-ja.com

Javaのスタックトレースなしの例外

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

ThrowableJavaalwaysにはスタックトレースが含まれていると信じていました。それが正しいか? exceptionswithoutスタックトレースをキャッチしたようです。理にかなっていますか?スタックトレースなしで例外をキャッチするのはpossibleですか?

44
Michael

スタックトレースなしでJavaでThrowableオブジェクトをキャッチすることができます。

Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace) 

指定した詳細メッセージ、原因、抑制を有効または無効にし、書き込み可能なスタックトレースを有効または無効にして、新しいスロー可能オブジェクトを構築します。

http://docs.Oracle.com/javase/7/docs/api/Java/lang/Throwable.html

33
Alex W

Java 6:

Java 6にはThrowable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)コンストラクタがないので、以下の手法を使用してスタックトレースの充填を抑制できます(Scalaから借用、 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のサブタイプではないため、Exceptionを使用してこれらの例外をExceptionできなくなり、代わりにNoStackTraceThrowableをキャッチするか、サブタイプ。

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

25
manikanta

Java 7+の場合、スタックトレースをオプションで抑止できる例外の例を次に示します。

public class SuppressableStacktraceException extends Exception {

    private boolean suppressStacktrace = false;

    public SuppressableStacktraceException(String message, boolean suppressStacktrace) {
        super(message, null, suppressStacktrace, !suppressStacktrace);
        this.suppressStacktrace = suppressStacktrace;
    }

    @Override
    public String toString() {
        if (suppressStacktrace) {
            return getLocalizedMessage();
        } else {
            return super.toString();
        }
    }
}

これは次の方法で実証できます。

try {
    throw new SuppressableStacktraceException("Not suppressed", false);
} catch (SuppressableStacktraceException e) {
    e.printStackTrace();
}
try {
    throw new SuppressableStacktraceException("Suppressed", true);
} catch (SuppressableStacktraceException e) {
    e.printStackTrace();
}

これは Apache SystemML のMLContextExceptionに基づいており、そのコードは https://github.com/Apache/systemml のGitHubで入手できます。

9
Deron

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

throwable.setStackTrace(new StackTraceElement[0]);

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

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

Throwableのスタックトレースはで初期化されます

Throwable#fillInStackTrace()

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

Throwable#getOurStackTrace()

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

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