如何最简单地将Throwable.getStackTrace()
的结果转换为描述堆栈跟踪的字符串?
如何最简单地将Throwable.getStackTrace()
的结果转换为描述堆栈跟踪的字符串?
这是一个可直接复制到代码中的版本:
import java.io.StringWriter;
import java.io.PrintWriter;
//Two lines of code to get the exception into a StringWriter
StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));
//And to actually print it
logger.info("Current stack trace is:\n" + sw.toString());
或者,在catch块中
} catch (Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
logger.info("Current stack trace is:\n" + sw.toString());
}
Arrays.toString(thrown.getStackTrace())
将结果转换成字符串的最简单方法,我在我的程序中使用它来打印堆栈跟踪。
LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});
在Throwable
上使用内置函数stackTraceToString()
。
扩展Throwable
类将给您提供字符串属性error.stackTraceString
:
val Throwable.stackTraceString: String
get() {
val sw = StringWriter()
val pw = PrintWriter(sw)
this.printStackTrace(pw)
return sw.toString()
}
如果你正在使用Java 8,尝试这个:
Arrays.stream(e.getStackTrace())
.map(s->s.toString())
.collect(Collectors.joining("\n"));
你可以在 Throwable.java
提供的 getStackTrace()
函数中找到代码:
public StackTraceElement[] getStackTrace() {
return getOurStackTrace().clone();
}
对于 StackTraceElement
,它提供了以下的toString()
方法:
public String toString() {
return getClassName() + "." + methodName +
(isNativeMethod() ? "(Native Method)" :
(fileName != null && lineNumber >= 0 ?
"(" + fileName + ":" + lineNumber + ")" :
(fileName != null ? "("+fileName+")" : "(Unknown Source)")));
}
所以只需将StackTraceElement
与"\n"连接即可。
将堆栈跟踪打印为字符串
import java.io.PrintWriter;
import java.io.StringWriter;
public class StackTraceUtils {
public static String stackTraceToString(StackTraceElement[] stackTrace) {
StringWriter sw = new StringWriter();
printStackTrace(stackTrace, new PrintWriter(sw));
return sw.toString();
}
public static void printStackTrace(StackTraceElement[] stackTrace, PrintWriter pw) {
for(StackTraceElement stackTraceEl : stackTrace) {
pw.println(stackTraceEl);
}
}
}
当你想要打印当前线程的堆栈跟踪,而又不想创建 Throwable
实例时,它会很有用 - 但请注意,创建新的 Throwable
并从中获取堆栈跟踪实际上比调用 Thread.getStackTrace
更快更便宜。
private String getCurrentStackTraceString() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
return Arrays.stream(stackTrace).map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));
}
代码来源于Apache Commons Lang 3.4 (JavaDoc):
public static String getStackTrace(final Throwable throwable) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
与其他答案的区别在于,它使用了PrintWriter
上的autoFlush
。
没有使用java.io.*
,可以这样做。
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
然后trace
变量将保存您的堆栈跟踪信息。输出还包含初始原因,输出与printStackTrace()
相同。
例如,printStackTrace()
会产生以下结果:
java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
trace
字符串保存了当被打印到 stdout
时的信息。java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
使用Java 8的Stream API,您可以进行以下操作:
Stream
.of(throwable.getStackTrace())
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));