64

我很好奇 printStackTrace() 和 toString() 之间有什么区别。乍一看,他们似乎在做同样的事情。

代码:

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

7 回答 7

97

不,有一个重要的区别!使用 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()只是返回一个字符串,并且不会打印任何内容。

于 2012-04-12T09:16:26.767 回答
62

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

public static String exceptionStacktraceToString(Exception e)
{
    return Arrays.toString(e.getStackTrace());
}
于 2012-04-13T08:24:14.890 回答
14

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

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

于 2012-04-12T09:17:49.897 回答
1

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

至于您的答案,您实际上可以看到这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();
}
于 2014-09-13T00:15:09.327 回答
1

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()不会打印任何内容。

于 2012-04-12T09:18:14.160 回答
1

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

public static @NotNull String toString(@NotNull Throwable e) {
    StringWriter sw = new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}
于 2017-02-24T02:51:01.317 回答
0

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

于 2018-08-20T11:05:41.787 回答