63

I'm curious as to what the difference is between printStackTrace() and toString(). At first sight, they seem to do the exact same thing.

Code:

try {
// Some code
} catch (Exception e)
   e.printStackTrace();
   // OR
   e.toString()
}
wattostudios
  • 8,666
  • 13
  • 43
  • 57
Andreas
  • 2,007
  • 5
  • 26
  • 37

7 Answers7

100

No, there is an important difference! Using toString, you only have the type of the exception and the error message. Using printStackTrace() you get the whole stacktrace of an exception, which is very helpful for debugging.

Example of System.out.println(toString()):

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

Example of 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)

To make a string of the whole stacktrace, I usually use this method:

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

Also note that simply calling toString() simply returns a string, and won't print anything out.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
62

To convert StackTrace to String a shorter implementation I use is:

public static String exceptionStacktraceToString(Exception e)
{
    return Arrays.toString(e.getStackTrace());
}
Renaud
  • 1,833
  • 19
  • 20
  • And much more useful, too, than direct printing. But as one string, attention to that! – Gangnus Nov 23 '17 at 11:18
  • 1
    If your project uses Apache commons-lang, this can also be accomplished with `org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)`, which will format it nicely as well – pterry26 Oct 15 '18 at 17:39
  • 4
    Note that this output would be different from `printStackTrace()` since `printStackTrace()` includes its cause's stacktrace recursively, whereas `getStackTrace()` does not. – Anmol Singh Jaggi Jan 23 '21 at 14:51
14

No, there's a huge difference. If you just call toString, it won't print anything - it will just return a string. A catch block of just e.toString(); is useless. (There's also the matter of the stack trace, as Martijn pointed out.)

Personally I wouldn't use either though - I'd use a logging library (log4j, java.util.logging etc) which takes the Throwable itself as a parameter, and will format it usefully - including the stack trace, potentially truncated to avoid repetition.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
1

toString () gives name of the exception class when exception is raised and printStackTrace () gives the entry hierarchy of method execution that were there when exception is raised in the application.

For the code

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

e.printStackTrace() will give

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)

While e.toString() will not print anything as Jon wrote in his answer.

vikiiii
  • 9,246
  • 9
  • 49
  • 68
1

I think that you want to get the output of Throwable.printStackTrace(), just like what I was looking for. I checked the Java source code and put together a String instead of writing to a PrintStream. It is somewhat more comprehensive than @MartijnCourteaux solution but feels a little like a hack to me.

As for your answer, you can actually see that Throwable.toString() is only a part of 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();
}
Kapé
  • 4,411
  • 3
  • 37
  • 54
  • 2
    FYI: just found out that on Android you can use [Log.getStackTraceString(java.lang.Throwable)](http://developer.android.com/reference/android/util/Log.html#getStackTraceString(java.lang.Throwable) "Android getStackTraceString(java.lang.Throwable)") directly. – Kapé Sep 13 '14 at 11:55
1

this is what I use for the full stack trace as a String

public static @NotNull String toString(@NotNull Throwable e) {
    StringWriter sw = new StringWriter();
    e.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}
ycomp
  • 8,316
  • 19
  • 57
  • 95
0

There is an Open Source java library called MgntUtils (written by me) that provides several methods that allow you to extract stacktrace as a String as well as to optionally filter based on parametric package prefix. See the javadoc for the method public static java.lang.String getStacktrace(java.lang.Throwable e, boolean cutTBS, java.lang.String relevantPackage) The library is available at Maven Central and Github

Michael Gantman
  • 7,315
  • 2
  • 19
  • 36