将Throwable.getStackTrace()的结果转换为描述堆栈跟踪的字符串最简单的方法是什么?
当前回答
以下代码允许您使用字符串格式获取整个stackTrace,而无需使用log4J或java.util.Logger等API:
catch (Exception e) {
StackTraceElement[] stack = e.getStackTrace();
String exception = "";
for (StackTraceElement s : stack) {
exception = exception + s.toString() + "\n\t\t";
}
System.out.println(exception);
// then you can send the exception string to a external file.
}
其他回答
Kotlin>=1.4
在Throwable上使用内置函数stackTraceToString()。
Kotlin<1.4
扩展Throwable类将提供String属性error.stackTraceString:
val Throwable.stackTraceString: String
get() {
val sw = StringWriter()
val pw = PrintWriter(sw)
this.printStackTrace(pw)
return 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});
如果您使用的是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)")));
}
因此,只需使用“\n”连接StackTraceElement。
我不久前写了一些方法,所以我想为什么不花我的两分钱。
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements) {
return stackTraceElementsToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceElementsToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += padding + (!stackTrace.toString().startsWith("Caused By") ? "\tat " : "") + stackTrace.toString() + lineSeparator;
}
}
return str;
}
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += (!stackTrace.toString().startsWith("Caused By") ? "" : padding + stackTrace.toString() + lineSeparator);
}
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e) {
return throwableToStrNoStackTraces(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator) {
return throwableToStrNoStackTraces(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceCausedByElementsOnlyToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + throwableToStrNoStackTraces(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStrNoStackTraces(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStr(Throwable e) {
return throwableToStr(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator) {
return throwableToStr(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = padding + e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceElementsToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + "Suppressed: " + throwableToStr(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStr(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
例子:
try(InputStream in = new FileInputStream(file)) {
...
} catch(IOException e) {
String exceptionToString = throwableToStr(e);
someLoggingUtility.println(exceptionToString);
...
}
打印:
java.io.FileNotFoundException: C:\test.txt (The system cannot find the file specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.gmail.br45entei.Example.main(Example.java:32)
如果你不想使用外部库,而且你不是为Android开发的,你可以创建这样的“扩展”方法:
public static String getStackTraceString(Throwable e) {
return getStackTraceString(e, "");
}
private static String getStackTraceString(Throwable e, String indent) {
StringBuilder sb = new StringBuilder();
sb.append(e.toString());
sb.append("\n");
StackTraceElement[] stack = e.getStackTrace();
if (stack != null) {
for (StackTraceElement stackTraceElement : stack) {
sb.append(indent);
sb.append("\tat ");
sb.append(stackTraceElement.toString());
sb.append("\n");
}
}
Throwable[] suppressedExceptions = e.getSuppressed();
// Print suppressed exceptions indented one level deeper.
if (suppressedExceptions != null) {
for (Throwable throwable : suppressedExceptions) {
sb.append(indent);
sb.append("\tSuppressed: ");
sb.append(getStackTraceString(throwable, indent + "\t"));
}
}
Throwable cause = e.getCause();
if (cause != null) {
sb.append(indent);
sb.append("Caused by: ");
sb.append(getStackTraceString(cause, indent));
}
return sb.toString();
}
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap