Разница между printStackTrace() и toString()
Мне любопытно, в чем разница между printStackTrace() и toString(). На первый взгляд кажется, что они делают то же самое.
Код:
try {
// Some code
} catch (Exception e)
e.printStackTrace();
// OR
e.toString()
}
7 ответов
Нет, есть важное отличие! Используя 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()
просто возвращает строку и ничего не печатает.
Чтобы преобразовать StackTrace в String, я использую более короткую реализацию:
public static String exceptionStacktraceToString(Exception e)
{
return Arrays.toString(e.getStackTrace());
}
Нет, есть огромная разница. Если вы просто позвоните toString
, он ничего не печатает - он просто вернет строку. Поймать блок просто e.toString();
бесполезно. (Существует также вопрос трассировки стека, как отметил Мартейн.)
Лично я не использовал бы, хотя - я бы использовал библиотеку журналов (log4j, java.util.logging и т. Д.), Которая принимает Throwable
сам как параметр, и будет форматировать его с пользой - включая трассировку стека, потенциально обрезанную, чтобы избежать повторения.
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()
не будет ничего печатать, как Джон написал в своем ответе.
Это то, что я использую для полной трассировки стека как String
public static @NotNull String toString(@NotNull Throwable e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
Я думаю, что вы хотите получить вывод Throwable.printStackTrace()
так же, как то, что я искал. Я проверил исходный код Java и собрал 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();
}
Существует библиотека Java с открытым исходным кодом под названием MgntUtils (написанная мной), которая предоставляет несколько методов, которые позволяют извлекать трассировку стека в виде строки, а также дополнительно фильтровать на основе параметрического префикса пакета. См. Javadoc для метода public static java.lang.String getStacktrace (java.lang.Throwable e, логический cutTBS, java.lang.String релевантный пакет). Библиотека доступна в центрах Maven и Github.