これはおそらく非常に素朴な質問です。
Throwable
のJava
alwaysにはスタックトレースが含まれていると信じていました。それが正しいか? exceptions
withoutスタックトレースをキャッチしたようです。理にかなっていますか?スタックトレースなしで例外をキャッチするのはpossibleですか?
スタックトレースなしでJavaでThrowableオブジェクトをキャッチすることができます。
Throwable(String message, Throwable cause, boolean enableSuppression,boolean writableStackTrace)
指定した詳細メッセージ、原因、抑制を有効または無効にし、書き込み可能なスタックトレースを有効または無効にして、新しいスロー可能オブジェクトを構築します。
http://docs.Oracle.com/javase/7/docs/api/Java/lang/Throwable.html
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
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で入手できます。
例外のスタックトレースを抑制する最も簡単な方法は
throwable.setStackTrace(new StackTraceElement[0]);
例外に原因がある場合、同じことを再帰的に行う必要がある場合があります。
これにより、スタックトレースのコストのかかる作成も可能な限り削減されます
Throwableのスタックトレースはで初期化されます
Throwable#fillInStackTrace()
、コンストラクターによって呼び出されるため、回避できません。スタックトレースが実際に使用されるとき、StackTraceElement []は遅延的に構築されます
Throwable#getOurStackTrace()
これは、フィールドThrowable.stackTraceがまだ設定されていない場合にのみ発生します。
スタックトレースをnull以外の値に設定すると、Throwable#getOurStackTrace()でStackTraceElement []の構築が回避され、パフォーマンスの低下が可能な限り軽減されます。