Czy istnieje sposób, aby Throwable.printStackTrace(PrintStream s)
wydrukować pełny ślad stosu, tak żebym mógł zobaczyć poza końcową linią "... 40 more"
?
Czy istnieje sposób, aby Throwable.printStackTrace(PrintStream s)
wydrukować pełny ślad stosu, tak żebym mógł zobaczyć poza końcową linią "... 40 more"
?
Odpowiedzi:
Nie musisz; ta informacja jest obecna w innym miejscu śladu stosu. Z dokumentów printStackTrace()
:
Zwróć uwagę na obecność linii zawierających znaki
"..."
. Te wiersze wskazują, że pozostała część śladu stosu dla tego wyjątku odpowiada wskazanej liczbie ramek od dołu śladu stosu wyjątku, który został spowodowany przez ten wyjątek (wyjątek „obejmujący”).Ten skrót może znacznie zmniejszyć długość wyjścia w typowym przypadku, gdy opakowany wyjątek jest wyrzucany z tej samej metody, co przechwytywany „wyjątek przyczynowy”.
Innymi słowy, "... x more"
jedyny pojawia się w łańcuchowym wyjątku i tylko wtedy, gdy ostatnie x
wiersze śladu stosu są już obecne jako część śladu stosu innego połączonego wyjątku.
Załóżmy, że metoda przechwytuje wyjątek Foo, zawija go w wyjątek Bar i rzuca Bar. Następnie ślad stosu Foo zostanie skrócony. Jeśli z jakiegoś powodu potrzebujesz pełnego śladu, wszystko co musisz zrobić, to wziąć ostatnią linię przed ...
śladem stosu w Foo i poszukać jej w śladzie stosu Bar; wszystko poniżej tej linii jest dokładnie tym, co byłoby wydrukowane w śladzie stosu Foo.
Weźmy ślad stosu z dokumentacji Throwable.printStackTrace () :
HighLevelException: MidLevelException: LowLevelException
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException: LowLevelException
at Junk.c(Junk.java:23)
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
... 1 more
Caused by: LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
... 3 more
Przyczyny są wyświetlane od najbardziej zagnieżdżonej na dole („główna przyczyna”) do tej, do której należy wydrukowany ślad stosu.
W tym przypadku główną przyczyną jest LowLevelException
, co spowodowało MidLevelException
, które spowodowało HighLevelException
.
Aby uzyskać pełny ślad stosu, musisz spojrzeć na ramki otaczającego wyjątku (i otaczających go wyjątków):
Więc gdybyśmy chcieli uzyskać pełny ślad stosu, wykonalibyśmy LowLevelException
następujące czynności:
MidLevelException
)
MidLevelException
( HighLevelException
)Twój pełny ślad stosu wygląda wtedy następująco:
LowLevelException
at Junk.e(Junk.java:30)
at Junk.d(Junk.java:27)
at Junk.c(Junk.java:21)
// From MidLevelException stack trace
at Junk.b(Junk.java:17)
at Junk.a(Junk.java:11)
// From HighLevelException stack trace
at Junk.main(Junk.java:4)
Uwagi dodatkowe:
Mogą wystąpić przypadki, w których nie ma na liście ramek, np .:
HighLevelException: MidLevelException
at Junk.main(Junk.java:4)
Caused by: MidLevelException
... 1 more
Może się to zdarzyć, gdy przyczyną jest tworzony w tej samej linii: new HighLevelException(new MidLevelException())
. Nie daj się zmylić, podejście opisane powyżej nadal działa, po prostu nie ma ramek do użycia z wyjątku, kontynuuj z jego obejmującą.
W niektórych przypadkach możesz zaoszczędzić sobie liczenia, patrząc na pierwszą klatkę, która nie została pominięta (powyższa linia ... X more
). Jeśli wiesz, które metody wywołują metodę w tym wierszu, możesz bezpośrednio szukać wywołań w ramkach otaczającego wyjątku:
HighLevelException: MidLevelException: LowLevelException
at Junk.c(Junk.java:29)
at Junk.b(Junk.java:21)
at Junk.a(Junk.java:13)
at Junk.main(Junk.java:4)
Caused by: MidLevelException
// You know Junk.d is only called by Junk.b
at Junk.d(Junk.java:35)
... 3 more
...
to pierwsza klatka, która się różni. Jednak będzie przynajmniej w tej samej klasie, co pomaga go znaleźć.