Difference between printStackTrace() and toString()

Java

Java Problem Overview


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

Java Solutions


Solution 1 - Java

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.

Solution 2 - Java

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

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

Solution 3 - Java

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.

Solution 4 - Java

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.

Solution 5 - Java

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

Solution 6 - Java

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

Solution 7 - Java

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAndreasView Question on Stackoverflow
Solution 1 - JavaMartijn CourteauxView Answer on Stackoverflow
Solution 2 - JavaRenaudView Answer on Stackoverflow
Solution 3 - JavaJon SkeetView Answer on Stackoverflow
Solution 4 - JavavikiiiiView Answer on Stackoverflow
Solution 5 - JavaKapéView Answer on Stackoverflow
Solution 6 - JavaycompView Answer on Stackoverflow
Solution 7 - JavaMichael GantmanView Answer on Stackoverflow