【问题标题】:Difference between printStackTrace() and toString()printStackTrace() 和 toString() 之间的区别
【发布时间】:2012-04-24 15:07:04
【问题描述】:

我很好奇 printStackTrace() 和 toString() 之间的区别。 乍一看,他们似乎做着完全相同的事情。

代码:

try {
// Some code
} catch (Exception e)
   e.printStackTrace();
   // OR
   e.toString()
}

【问题讨论】:

  • 嗯,它们之间的关系模糊,但它们根本不做同样的事情。
  • 我假设您打算将toString() 的结果打印到System.err...?

标签: java


【解决方案1】:

不,有一个重要的区别!使用 toString,您只有异常的类型和错误消息。使用 printStackTrace() 可以获得异常的整个堆栈跟踪,这对调试非常有帮助。

System.out.println(toString()) 示例:

java.io.FileNotFoundException: yourFile.txt (The system cannot find the file specified)

printStackTrace() 示例:

java.io.FileNotFoundException: yourFile.txt (The system cannot find the file specified)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.(FileInputStream.java:106)
at java.io.FileReader.(FileReader.java:55)
at ReadFromFile.main(ReadFromFile.java:14)

要制作整个堆栈跟踪的字符串,我通常使用这种方法:

public static String exceptionStacktraceToString(Exception e)
{
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    PrintStream ps = new PrintStream(baos);
    e.printStackTrace(ps);
    ps.close();
    return baos.toString();
}

另请注意,简单地调用toString() 只会返回一个字符串,并且不会打印任何内容。

【讨论】:

  • 有没有办法将堆栈跟踪存储为字符串?
  • +1 获取 toString() 返回的具体示例。该方法也很有帮助,尽管我更喜欢@RenaudBlue 的单行版本。
【解决方案2】:

不,有很大的不同。如果您只是调用toString,它不会打印任何东西 - 它只会返回一个字符串。仅 e.toString(); 的 catch 块是没有用的。 (正如 Martijn 所指出的,还有堆栈跟踪的问题。)

虽然我个人不会使用任何一个 - 我会使用一个日志库(log4j、java.util.logging 等),它将 Throwable 本身作为参数,并将有用地格式化它 - 包括堆栈跟踪, 可能会被截断以避免重复。

【讨论】:

    【解决方案3】:

    toString () 在引发异常时给出异常类的名称,printStackTrace () 给出在应用程序中引发异常时所在的方法执行的条目层次结构。

    代码

        try 
        {
            List<String>  n =new ArrayList<String>();
            String i = n.get(3); 
        }catch (Exception e) {
            e.printStackTrace();
        }
       }
    

    e.printStackTrace()会给

    java.lang.IndexOutOfBoundsException: Index: 3, Size: 0
        at java.util.ArrayList.RangeCheck(ArrayList.java:547)
        at java.util.ArrayList.get(ArrayList.java:322)
        at com.o2.business.util.Trial.test(CommonUtilsTest.java:866)
    

    虽然 e.toString() 不会像 Jon 在他的回答中写的那样打印任何内容。

    【讨论】:

      【解决方案4】:

      要将 StackTrace 转换为 String,我使用的更短的实现是:

      public static String exceptionStacktraceToString(Exception e)
      {
          return Arrays.toString(e.getStackTrace());
      }
      

      【讨论】:

      • 而且比直接打印更有用。但作为一个字符串,请注意!
      • 如果您的项目使用 Apache commons-lang,这也可以使用 org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable) 来完成,它也会很好地格式化它
      • 请注意,此输出与printStackTrace() 不同,因为printStackTrace() 递归包含其原因的堆栈跟踪,而getStackTrace() 不包含。
      【解决方案5】:

      我认为你想得到Throwable.printStackTrace() 的输出,就像我正在寻找的一样。我检查了 Java 源代码并将String 放在一起,而不是写给PrintStream。它比 @MartijnCourteaux 解决方案更全面,但对我来说有点像 hack。

      至于你的回答,其实你可以看到Throwable.toString()只是Throwable.printStackTrace()的一部分:

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

      【讨论】:

      【解决方案6】:

      这是我用于完整堆栈跟踪的 String

      public static @NotNull String toString(@NotNull Throwable e) {
          StringWriter sw = new StringWriter();
          e.printStackTrace(new PrintWriter(sw));
          return sw.toString();
      }
      

      【讨论】:

        【解决方案7】:

        有一个名为 MgntUtils 的开源 java 库(由我编写),它提供了几种方法,允许您将堆栈跟踪提取为字符串,并可选择基于参数包前缀进行过滤。有关方法public static java.lang.String getStacktrace(java.lang.Throwable e, boolean cutTBS, java.lang.String relevantPackage),请参阅 javadoc 该库位于Maven CentralGithub

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-02-19
          • 2019-04-27
          • 2011-01-07
          • 2011-02-22
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多