1. Pagkuha ng stack trace

Pagkuha ng stack trace

Nag-aalok ang Java programming language ng maraming paraan para makakuha ng impormasyon ang programmer tungkol sa kung ano ang nangyayari sa isang program. At hindi lang salita.

Halimbawa, pagkatapos ma-compile ang mga C++ program, nagiging isang malaking file ang mga ito na puno ng machine code, at ang available lang sa isang programmer sa runtime ay ang address ng block ng memorya na naglalaman ng machine code na kasalukuyang isinasagawa. Hindi marami, sabihin nating.

Ngunit para sa Java, kahit na matapos ang isang programa ay naipon, ang mga klase ay nananatiling mga klase, ang mga pamamaraan at mga variable ay hindi nawawala, at ang programmer ay may maraming mga paraan upang makakuha ng impormasyon tungkol sa kung ano ang nangyayari sa programa.

Stack trace

Halimbawa, sa punto sa pagpapatupad ng isang programa, maaari mong malaman ang klase at pangalan ng pamamaraan na kasalukuyang isinasagawa. At hindi lamang isang paraan — maaari kang makakuha ng impormasyon tungkol sa buong hanay ng mga tawag sa pamamaraan mula sa kasalukuyang pamamaraan pabalik sa main()pamamaraan.

Ang isang listahan na binubuo ng kasalukuyang pamamaraan, at ang paraan na nag-invoke nito, at ang paraan na tumawag sa isang iyon, atbp. ay tinatawag na stack trace . Makukuha mo ito gamit ang pahayag na ito:

StackTraceElement[] methods = Thread.currentThread().getStackTrace();

Maaari mo ring isulat ito bilang dalawang linya:

Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();

Ang static currentThread()na paraan ng Threadklase ay nagbabalik ng isang sanggunian sa isang Threadbagay, na naglalaman ng impormasyon tungkol sa kasalukuyang thread, ibig sabihin, ang kasalukuyang thread ng pagpapatupad. Matututo ka pa tungkol sa mga thread sa Level 17 at 18 ng Java Core quest.

Ang bagay na ito Threaday may isang getStackTrace()pamamaraan, na nagbabalik ng isang hanay ng StackTraceElementmga bagay, na ang bawat isa ay naglalaman ng impormasyon tungkol sa isang pamamaraan. Kung pinagsama-sama, ang lahat ng elementong ito ay bumubuo ng isang stack trace .

Halimbawa:

Code
public class Main
{
   public static void main(String[] args)
   {
      test();
   }

   public static void test()
   {
      Thread current = Thread.currentThread();
      StackTraceElement[] methods = current.getStackTrace();

      for(var info: methods)
         System.out.println(info);
   }
}
Output ng console
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)

Tulad ng nakikita natin sa console output ng halimbawa, ang getStackTrace()pamamaraan ay nagbalik ng hanay ng tatlong elemento:

  • getStackTrace()paraan ng Threadklase
  • test()paraan ng Mainklase
  • main()paraan ng Mainklase

Mula sa stack trace na ito, maaari nating tapusin na:

  • Ang Thread.getStackTrace()pamamaraan ay tinawag ng Main.test()pamamaraan sa linya 11 ng Main.java file
  • Ang Main.test()pamamaraan ay tinawag ng Main.main()pamamaraan sa linya 5 ng Main.java file
  • Walang tumawag sa Main.main()pamamaraan — ito ang unang paraan sa hanay ng mga tawag.

Sa pamamagitan ng paraan, ilan lamang sa mga magagamit na impormasyon ang ipinakita sa screen. Lahat ng iba pa ay maaaring makuha nang direkta mula sa StackTraceElementbagay



2.StackTraceElement

Gaya ng ipinahihiwatig ng pangalan nito, StackTraceElementnilikha ang klase upang mag-imbak ng impormasyon tungkol sa isang elemento ng stack trace , ibig sabihin, isang paraan sa stack trace.

Ang klase na ito ay may mga sumusunod na pamamaraan ng halimbawa:

Pamamaraan Paglalarawan
String getClassName()
Ibinabalik ang pangalan ng klase
String getMethodName()
Ibinabalik ang pangalan ng pamamaraan
String getFileName()
Ibinabalik ang pangalan ng file (ang isang file ay maaaring maglaman ng maraming klase)
int getLineNumber()
Ibinabalik ang numero ng linya sa file kung saan tinawag ang pamamaraan
String getModuleName()
Ibinabalik ang pangalan ng module (maaaring ito ay null)
String getModuleVersion()
Ibinabalik ang bersyon ng module (maaaring ito ay null)

Matutulungan ka nilang makakuha ng mas kumpletong impormasyon tungkol sa kasalukuyang stack ng tawag:

Code Output ng console Tandaan
public class Main
{
   public static void main(String[] args)
   {
      test();
   }

   public static void test()
   {
      Thread current = Thread.currentThread();
      StackTraceElement[] methods = current.getStackTrace();

      for(StackTraceElement info: methods)
      {
         System.out.println(info.getClassName());
         System.out.println(info.getMethodName());

         System.out.println(info.getFileName());
         System.out.println(info.getLineNumber());

         System.out.println(info.getModuleName());
         System.out.println(info.getModuleVersion());
         System.out.println();
      }
   }
}
java.lang.Thread
getStackTrace
Thread.java
1606
java.base
11.0.2

Main
test
Main.java
11
null
null

Main
main
Main.java
5
null
null
pangalan ng klase
ng paraan pangalan ng
file name
line number module
name
module version

name class name method
name
file name line number module name module version name ng class name method name file name line number module name module version











3. Salansan

Alam mo na kung ano ang stack trace , ngunit ano ang stack (Stack class)?

Ang stack ay isang istraktura ng data kung saan maaari kang magdagdag ng mga elemento at kung saan maaari kang kumuha ng mga elemento. Sa paggawa nito, maaari ka lamang kumuha ng mga elemento mula sa dulo: kunin mo muna ang huling idinagdag, pagkatapos ay idinagdag ang pangalawa hanggang sa huli, atbp.

Ang name stack mismo ay nagmumungkahi ng pag-uugaling ito, tulad ng kung paano ka makikipag-ugnayan sa isang stack ng mga papel. Kung inilagay mo ang mga sheet 1, 2 at 3 sa isang stack, kailangan mong kunin ang mga ito sa reverse order: una ang ikatlong sheet, pagkatapos ay ang pangalawa, at pagkatapos lamang ang una.

Ang Java ay mayroon ding espesyal na klase ng koleksyon ng Stack na may parehong pangalan at gawi. Ang klase na ito ay nagbabahagi ng maraming pag-uugali kay ArrayListat LinkedList. Ngunit mayroon din itong mga pamamaraan na nagpapatupad ng pag-uugali ng stack:

Paraan Paglalarawan
T push(T obj)
Idinaragdag ang objelemento sa tuktok ng stack
T pop()
Kinukuha ang elemento mula sa tuktok ng stack (bumababa ang lalim ng stack)
T peek()
Ibinabalik ang item sa tuktok ng stack (ang stack ay hindi nagbabago)
boolean empty()
Tinitingnan kung walang laman ang koleksyon
int search(Object obj)
Naghahanap ng isang bagay sa koleksyon at ibinalik itoindex

Halimbawa:

Code Mga nilalaman ng stack (nasa kanan ang tuktok ng stack)
Stack<Integer> stack = new Stack<Integer>();
stack.push(1);
stack.push(2);
stack.push(3);
int x = stack.pop();
stack.push(4);
int y = stack.peek();
stack.pop();
stack.pop();

[1]
[1, 2]
[1, 2, 3]
[1, 2]
[1, 2, 4]
[1, 2, 4]
[1, 2]
[1]

Ang mga stack ay madalas na ginagamit sa programming. Kaya ito ay isang kapaki-pakinabang na koleksyon.



4. Pagpapakita ng stack trace habang pinangangasiwaan ang exception

Bakit tinatawag na stack trace ang isang listahan ng mga tawag sa pamamaraan ? Dahil kung iisipin mo ang listahan ng mga pamamaraan bilang isang stack ng mga sheet ng papel na may mga pangalan ng pamamaraan, pagkatapos ay kapag tinawag mo ang susunod na pamamaraan, magdagdag ka ng isang sheet na may pangalan ng pamamaraang iyon sa stack. At ang susunod na sheet ng papel ay napupunta sa ibabaw ng iyon, at iba pa.

Kapag natapos ang isang paraan, ang sheet sa tuktok ng stack ay aalisin. Hindi mo maaaring alisin ang isang sheet mula sa gitna ng stack nang hindi inaalis ang lahat ng mga sheet sa itaas nito. Katulad nito, hindi mo maaaring wakasan ang isang paraan sa gitna ng isang hanay ng mga tawag nang hindi tinatapos ang lahat ng mga pamamaraan na tinawag nito.

Mga pagbubukod

Ang isa pang kawili-wiling paggamit para sa mga stack ay sa panahon ng paghawak ng exception.

Kapag naganap ang isang error sa isang programa at ang isang exception ay itinapon , ang exception ay naglalaman ng kasalukuyang stack traceisang array na binubuo ng isang listahan ng mga pamamaraan na nagsisimula, mula sa pangunahing pamamaraan at nagtatapos sa paraan kung saan nangyari ang error. Mayroong kahit na linya kung saan ang pagbubukod ay itinapon!

Ang stack trace na ito ay nakaimbak sa loob ng exception at madaling makuha mula dito gamit ang sumusunod na paraan:StackTraceElement[] getStackTrace()

Halimbawa:

Code Tandaan
try
{
   // An exception may occur here
}
catch(Exception e)
{
   StackTraceElement[] methods = e.getStackTrace()
}




Catch the exception

Kunin ang stack trace na umiral noong nangyari ang error.

Ito ay isang pamamaraan ng Throwableklase, kaya lahat ng mga inapo nito (ibig sabihin, lahat ng mga pagbubukod) ay mayroong getStackTrace()pamamaraan. Super convenient, ha?

Ipakita ang stack trace ng exception

Sa pamamagitan ng paraan, ang Throwableklase ay may isa pang paraan para sa pagtatrabaho sa mga stack traces, isang paraan na nagpapakita ng lahat ng impormasyon ng stack trace na nakaimbak sa loob ng exception. Ito ay tinatawag na printStackTrace().

Medyo maginhawa, maaari mo itong tawagan sa anumang pagbubukod.

Halimbawa:

Code
try
{
   // An exception may occur here
}
catch(Exception e)
{
   e.printStackTrace();
}
Output ng console
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)