【问题标题】:How can I convert a stack trace to a string?如何将堆栈跟踪转换为字符串?
【发布时间】:2010-11-12 02:11:33
【问题描述】:

Throwable.getStackTrace() 的结果转换为描述堆栈跟踪的字符串的最简单方法是什么?

【问题讨论】:

  • 因为 jqno 的答案实际上使用了您在问题中指定的 Throwable.getStackTrace() 方法,而 Brian 没有。他改用 Throwable.printStackTrace()。
  • 几乎每个 Java 项目都应该包含 Apache commons-lang。它包括许多实现极其常见的开发需求的便捷方法。
  • @StijndeWitt 这三行代码几乎肯定需要在您调用它们的地方进行分解。由于您不知道将它们放在哪里,它们将与所有其他有用的 sn-ps 一起进入您的实用工具箱。答对了!您刚刚重新发明了番石榴 / commons-lang / 任何东西......只是不太好。而是导入一个合理的实用程序库,并节省重新发明轮子。 新手的真正标志是认为你可以比图书馆作家做得更好。
  • 1. Guava 有 - Throwables.getStackTraceAsString(e) 2. Apache Commons Lang - ExceptionUtils.getFullStackTrace 3. 编写我们自己的自定义方法
  • @AndrewSpencer 我不明白你们为什么要如此努力地抨击 StijndeWitt 想要通过一些小的 sn-p 来实现这一目标。编写一个小型实用程序方法确实没有太大的危险(我不认为它是“纯粹的傲慢哦不!他认为他比 Apache 更好!!”)。有很多项目,尤其是在非 Java JVM 语言中,它们真的不想包含 Guava 或 Commons Lang 来记录堆栈跟踪。我编写了 Scala 和 Clojure 库,当然不会让 Apache Commons Lang 成为一种传递依赖项。

标签: java stack-trace tostring


【解决方案1】:

使用Throwable.printStackTrace(PrintWriter pw) 将堆栈跟踪发送给适当的写入者。

import java.io.StringWriter;
import java.io.PrintWriter;

// ...

StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
System.out.println(sStackTrace);

【讨论】:

  • 这会修剪堆栈跟踪,与 printStackTrace() 相同。堆栈中的所有异常都是可见的,但对于每个异常,堆栈可能会被修剪。任何需要整个跟踪的人都应该考虑这一点。
  • 事实证明,这几乎正是 apache 的 ExceptionUtils.getStackTrace() 方法所做的。实际上几乎是信。
  • @BrianAgnew,你不应该关闭StringWriterPrintWriter 吗?
  • @MuhammadGelbana - 是的。以上是为了方便起见。我怀疑如果你不这样做不会造成问题,但我会以良好的实践为由提倡它
  • @BrianAgnew,感谢您的回复。这让我很好奇,这就是我发现的:stackoverflow.com/questions/14542535/…
【解决方案2】:

可以使用以下方法将Exception 堆栈跟踪转换为String。这个类在 Apache commons-lang 中可用,这是最常见的依赖库,有许多流行的开源代码

org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)

【讨论】:

  • @Stijn - 公平地说(我在下面写了当前投票最高的答案)值得查看 commons-lang 以获得更多功能
  • @StijndeWitt Commons Lang 很常见。它已经出现在我工作中的大多数项目/项目中。
  • @Hugo 谢谢,打算使用 StringWriter 来避免添加新库——结果它已经是我的 3 个依赖项的依赖项。所以剩下的,检查你是否已经拥有它。
  • @MartinAsenov - 按照您的逻辑,您永远不会使用这样的库,对吗?除非您已经在使用它,否则您不会使用它?
  • 仅供参考,包已更改,课程现在位于:org.apache.commons.lang3.exception.ExceptionUtils
【解决方案3】:

这应该有效:

StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();

【讨论】:

  • java 上下文中的简洁总是令人讨厌的。 printStackTrace 应该只返回字符串,将是否打印它的决定留给用户:)
  • printStackTrace 在控制台中打印是可以接受的,但默认情况下至少应该可以使用 getStackTrace 作为字符串返回
  • 这部分内容简洁?除了将堆栈跟踪放入字符串之外,您必须构造 2 个没有其他目的的对象。
  • @dmitry 一个名为 printXXX() 的方法应该打印 XXX。
  • @Greg 实际上这甚至不是讽刺,只是需要简单地阅读他所说的话。
【解决方案4】:

如果您正在为 Android 开发,一个更简单的方法是使用这个:

import android.util.Log;

String stackTrace = Log.getStackTraceString(exception); 

格式与getStacktrace相同,例如

09-24 16:09:07.042: I/System.out(4844): java.lang.NullPointerException
09-24 16:09:07.042: I/System.out(4844):   at com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43)
09-24 16:09:07.042: I/System.out(4844):   at android.app.Activity.performCreate(Activity.java:5248)
09-24 16:09:07.043: I/System.out(4844):   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread.access$800(ActivityThread.java:139)
09-24 16:09:07.043: I/System.out(4844):   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
09-24 16:09:07.043: I/System.out(4844):   at android.os.Handler.dispatchMessage(Handler.java:102)
09-24 16:09:07.043: I/System.out(4844):   at android.os.Looper.loop(Looper.java:136)
09-24 16:09:07.044: I/System.out(4844):   at android.app.ActivityThread.main(ActivityThread.java:5097)
09-24 16:09:07.044: I/System.out(4844):   at java.lang.reflect.Method.invokeNative(Native Method)
09-24 16:09:07.044: I/System.out(4844):   at java.lang.reflect.Method.invoke(Method.java:515)
09-24 16:09:07.044: I/System.out(4844):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
09-24 16:09:07.044: I/System.out(4844):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)

【讨论】:

    【解决方案5】:

    Guava 的Throwables

    如果您有实际的Throwable 实例,Google Guava 将提供Throwables.getStackTraceAsString()

    例子:

    String s = Throwables.getStackTraceAsString ( myException ) ;
    

    【讨论】:

      【解决方案6】:

      警告:不包括原因(这通常是有用的部分!)

      public String stackTraceToString(Throwable e) {
          StringBuilder sb = new StringBuilder();
          for (StackTraceElement element : e.getStackTrace()) {
              sb.append(element.toString());
              sb.append("\n");
          }
          return sb.toString();
      }
      

      【讨论】:

        【解决方案7】:

        对我来说,最干净、最简单的方法是:

        import java.util.Arrays;
        Arrays.toString(e.getStackTrace());
        

        【讨论】:

        • 代码是干净的,但输出不是。最后你必须做一个 .replaceAll(", ", "\n") 。但是,您会丢失 printStackTrace 建议的缩进。
        • 这在您在单行中记录跟踪时很有用
        【解决方案8】:
        public static String getStackTrace(Throwable t) {
            StringWriter sw = new StringWriter();
            t.printStackTrace(new PrintWriter(sw));
            return sw.toString();
        }
        

        【讨论】:

        • 嗨,我只想指出,引用的答案的 cmets 部分指出 StringWriterPrintWriter 对象应该是 closed....(或者我猜只有PrintWriter 需要关闭,因为关闭它也应该关闭StringWriter
        【解决方案9】:

        以下代码允许您以String 格式获取整个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.
        }
        

        【讨论】:

          【解决方案10】:

          将堆栈跟踪打印到PrintStream,然后将其转换为String

          // ...
          
          catch (Exception e)
          {
              ByteArrayOutputStream out = new ByteArrayOutputStream(); 
              e.printStackTrace(new PrintStream(out));
              String str = new String(out.toByteArray());
          
              System.out.println(str);
          }
          

          【讨论】:

            【解决方案11】:

            这是一个可以直接复制粘贴到代码中的版本:

            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());
            }
            

            【讨论】:

              【解决方案12】:
              Arrays.toString(thrown.getStackTrace())
              

              是将结果转换为String的最简单方法 我在我的程序中使用它来打印堆栈跟踪

              LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});
              

              【讨论】:

                【解决方案13】:

                科特林 >= 1.4

                Throwable 上使用内置函数stackTraceToString()

                科特林

                扩展 Throwable 类将为您提供 String 属性 error.stackTraceString

                val Throwable.stackTraceString: String
                  get() {
                    val sw = StringWriter()
                    val pw = PrintWriter(sw)
                    this.printStackTrace(pw)
                    return sw.toString()
                  }
                

                【讨论】:

                【解决方案14】:

                如果你使用的是 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

                【讨论】:

                • 如果你想限制它,你可以在流上使用方法limit(5)。
                【解决方案15】:

                将堆栈跟踪打印到字符串

                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 更快且更便宜。

                【讨论】:

                  【解决方案16】:
                  private String getCurrentStackTraceString() {
                      StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
                      return Arrays.stream(stackTrace).map(StackTraceElement::toString)
                              .collect(Collectors.joining("\n"));
                  }
                  

                  【讨论】:

                    【解决方案17】:

                    代码来自 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

                    【讨论】:

                      【解决方案18】:

                      第一组cmet中的巧妙狙击非常有趣,但这真的取决于你想要做什么。 如果您还没有正确的库,那么 3 行代码(如 D. Wroblewski 的回答)是完美的。 OTOH,如果您已经拥有 apache.commons 库(就像大多数大型项目一样),那么 Amar 的答案会更短。 好的,获取库并正确安装它可能需要十分钟(如果您知道自己在做什么,则不到一分钟)。但是时间在流逝,因此您可能没有时间闲置。 Jarek Przygódzki 有一个有趣的警告——“如果你不需要嵌套异常”。

                      但是如果我确实需要完整的堆栈跟踪,嵌套和所有?在这种情况下,秘诀就是使用 apache.common 的 getFullStackTrace(参见 http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29

                      它救了我的培根。谢谢 Amar 的提示!

                      【讨论】:

                        【解决方案19】:

                        没有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)
                        

                        当打印到 stdout 时,trace 字符串保持不变

                        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)
                        

                        【讨论】:

                          【解决方案20】:

                          使用 Java 8 Stream API,您可以执行以下操作:

                          Stream
                              .of(throwable.getStackTrace())
                              .map(StackTraceElement::toString)
                              .collect(Collectors.joining("\n"));
                          

                          它将获取堆栈跟踪元素数组,将它们转换为字符串并加入多行字符串。

                          【讨论】:

                          • 此解决方案正在删除消息并忽略所有父跟踪
                          【解决方案21】:

                          对 Gala 的回答进行了扩展,其中还将包括异常的原因:

                          private String extrapolateStackTrace(Exception ex) {
                              Throwable e = ex;
                              String trace = e.toString() + "\n";
                              for (StackTraceElement e1 : e.getStackTrace()) {
                                  trace += "\t at " + e1.toString() + "\n";
                              }
                              while (e.getCause() != null) {
                                  e = e.getCause();
                                  trace += "Cause by: " + e.toString() + "\n";
                                  for (StackTraceElement e1 : e.getStackTrace()) {
                                      trace += "\t at " + e1.toString() + "\n";
                                  }
                              }
                              return trace;
                          }
                          

                          【讨论】:

                            【解决方案22】:

                            Scala 版本

                            def stackTraceToString(e: Exception): String = {
                              import java.io.PrintWriter
                              val sw = new StringWriter()
                              e.printStackTrace(new PrintWriter(sw))
                              sw.toString
                            }
                            

                            【讨论】:

                              【解决方案23】:

                              解决方法是将数组的stackTrace转换为字符串数据类型。请参阅以下示例:

                              import java.util.Arrays;
                              
                              try{
                              
                              }catch(Exception ex){
                                  String stack = Arrays.toString(ex.getStackTrace());
                                  System.out.println("stack "+ stack);
                              }
                              

                              【讨论】:

                                【解决方案24】:

                                如果您不想使用外部库并且不开发for Android,您可以像这样创建'extension' method

                                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();
                                }
                                

                                【讨论】:

                                  【解决方案25】:

                                  我的 oneliner 将堆栈跟踪转换为封闭的多行字符串:

                                  Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))
                                  

                                  易于“按原样”传递给记录器。

                                  【讨论】:

                                  • 你会得到与printStackTrace()不同的东西在这里你会失去:1)抛出的异常; 2) 原因及其堆栈跟踪
                                  • 差异在意料之中,因为转换 printStackTrace() 从来都不是问题的一部分。
                                  【解决方案26】:
                                   import java.io.PrintWriter;
                                  import java.io.StringWriter;
                                  
                                  public class PrintStackTrace {
                                  
                                      public static void main(String[] args) {
                                  
                                          try {
                                              int division = 0 / 0;
                                          } catch (ArithmeticException e) {
                                              StringWriter sw = new StringWriter();
                                              e.printStackTrace(new PrintWriter(sw));
                                              String exceptionAsString = sw.toString();
                                              System.out.println(exceptionAsString);
                                          }
                                      }
                                  }
                                  

                                  当你运行程序时,输出会是类似的:

                                  java.lang.ArithmeticException: / by zero
                                  at PrintStackTrace.main(PrintStackTrace.java:9)
                                  

                                  【讨论】:

                                    【解决方案27】:

                                    老问题,但我想补充一下您不想打印所有堆栈的特殊情况, 通过删除一些您实际上不感兴趣的部分,不包括某些类或包。

                                    使用SelectivePrintWriter 代替PrintWriter

                                    // This filters out this package and up.
                                    String packageNameToFilter = "org.springframework";
                                    
                                    StringWriter sw = new StringWriter();
                                    PrintWriter pw = new SelectivePrintWriter(sw, packageNameToFilter);
                                    e.printStackTrace(pw);
                                    String sStackTrace = sw.toString(); 
                                    System.out.println(sStackTrace);
                                    

                                    SelectivePrintWriter 类由以下给出:

                                    public class SelectivePrintWriter extends PrintWriter {
                                        private boolean on = true;
                                        private static final String AT = "\tat";
                                        private String internal;
                                    
                                        public SelectivePrintWriter(Writer out, String packageOrClassName) {
                                            super(out);
                                            internal = "\tat " + packageOrClassName;
                                        }
                                    
                                        public void println(Object obj) {
                                            if (obj instanceof String) {
                                                String txt = (String) obj;
                                                if (!txt.startsWith(AT)) on = true;
                                                else if (txt.startsWith(internal)) on = false;
                                                if (on) super.println(txt);
                                            } else {
                                                super.println(obj);
                                            }
                                        }
                                    }
                                    

                                    请注意,此类可以很容易地适应正则表达式、contains 或其他条件进行过滤。另请注意,这取决于Throwable 的实现细节(不太可能改变,但仍然如此)。

                                    【讨论】:

                                      【解决方案28】:

                                      警告:这可能有点跑题了,但是哦,好吧... ;)

                                      我不知道最初的海报是什么原因 是因为希望堆栈跟踪首先作为字符串。当堆栈跟踪应该在 SLF4J/Logback LOG 中结束,但没有或应该抛出异常时,这就是我所做的:

                                      public void remove(List<String> ids) {
                                          if(ids == null || ids.isEmpty()) {
                                              LOG.warn(
                                                  "An empty list (or null) was passed to {}.remove(List). " +
                                                  "Clearly, this call is unneccessary, the caller should " + 
                                                  "avoid making it. A stacktrace follows.", 
                                                  getClass().getName(),
                                                  new Throwable ("Stacktrace")
                                              );
                                      
                                              return;
                                          }
                                      
                                          // actual work, remove stuff
                                      }
                                      

                                      我喜欢它,因为它不需要外部库(当然,除了您的日志记录后端,它在大多数情况下都会存在)。

                                      【讨论】:

                                        【解决方案29】:

                                        几个选项

                                        1. StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); String exceptionAsString = sw.toString();

                                        2. 使用 Google Guava 库 String stackTrace = Throwables.getStackTraceAsString ( myException ) ;

                                        3. org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)

                                        【讨论】:

                                          【解决方案30】:

                                          前段时间我为此写了一些方法,所以我想为什么不把我的两分钱花在这个上。

                                          /** @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)
                                          

                                          【讨论】:

                                            猜你喜欢
                                            • 2013-09-04
                                            • 2015-08-23
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 1970-01-01
                                            • 2013-10-06
                                            • 2013-06-23
                                            相关资源
                                            最近更新 更多