1. Mendapatkan jejak tumpukan

Mendapatkan jejak tumpukan

Bahasa pemrograman Java menawarkan banyak cara bagi seorang programmer untuk mendapatkan informasi tentang apa yang sedang terjadi dalam sebuah program. Dan bukan hanya kata-kata.

Misalnya, setelah program C++ dikompilasi, mereka menjadi satu file besar yang penuh dengan kode mesin, dan semua yang tersedia bagi pemrogram saat runtime adalah alamat blok memori yang berisi kode mesin yang sedang dieksekusi. Tidak banyak, katakanlah.

Tetapi untuk Java, bahkan setelah sebuah program dikompilasi, kelas tetap menjadi kelas, metode dan variabel tidak hilang, dan pemrogram memiliki banyak cara untuk mendapatkan informasi tentang apa yang terjadi di dalam program.

Jejak tumpukan

Misalnya, pada saat eksekusi program, Anda dapat mengetahui kelas dan nama metode yang sedang dieksekusi. Dan bukan hanya satu metode — Anda bisa mendapatkan informasi tentang seluruh rangkaian pemanggilan metode dari metode saat ini kembali ke metode main().

Daftar yang terdiri dari metode saat ini, dan metode yang memanggilnya, dan metode yang memanggilnya, dll. disebut stack trace . Anda bisa mendapatkannya dengan pernyataan ini:

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

Anda juga dapat menuliskannya sebagai dua baris:

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

currentThread()Metode statis Threadkelas mengembalikan referensi ke objek Thread, yang berisi informasi tentang utas saat ini, yaitu utas eksekusi saat ini. Anda akan mempelajari lebih lanjut tentang utas di Level 17 dan 18 dari misi Java Core .

Objek ini Threadmemiliki getStackTrace()metode, yang mengembalikan array StackTraceElementobjek, yang masing-masing berisi informasi tentang metode. Secara bersama-sama, semua elemen ini membentuk jejak tumpukan .

Contoh:

Kode
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);
   }
}
Keluaran konsol
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)

Seperti yang bisa kita lihat di output konsol contoh, getStackTrace()metode ini mengembalikan array dari tiga elemen:

  • getStackTrace()metode Threadkelas
  • test()metode Mainkelas
  • main()metode Mainkelas

Dari stack trace ini, kita dapat menyimpulkan bahwa:

  • Metode tersebut Thread.getStackTrace()dipanggil dengan Main.test()metode pada baris 11 dari file Main.java
  • Metode tersebut Main.test()dipanggil dengan Main.main()metode pada baris 5 dari file Main.java
  • Tidak ada yang memanggil Main.main()metode tersebut — ini adalah metode pertama dalam rantai panggilan.

Omong-omong, hanya beberapa informasi yang tersedia yang ditampilkan di layar. Segala sesuatu yang lain dapat diperoleh langsung dari StackTraceElementobjek



2.StackTraceElement

Seperti namanya, StackTraceElementkelas dibuat untuk menyimpan informasi tentang elemen pelacakan tumpukan , yaitu salah satu metode dalam file stack trace.

Kelas ini memiliki metode contoh berikut:

metode Keterangan
String getClassName()
Mengembalikan nama kelas
String getMethodName()
Mengembalikan nama metode
String getFileName()
Mengembalikan nama file (satu file dapat berisi banyak kelas)
int getLineNumber()
Mengembalikan nomor baris dalam file tempat metode dipanggil
String getModuleName()
Mengembalikan nama modul (ini bisa null)
String getModuleVersion()
Mengembalikan versi modul (ini bisa null)

Mereka dapat membantu Anda mendapatkan informasi yang lebih lengkap tentang tumpukan panggilan saat ini:

Kode Keluaran konsol Catatan
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
nama kelas nama
metode nama
file
nomor baris
nama
modul versi modul nama

kelas nama metode nama file nomor baris nama modul versi modul nama kelas nama metode nama file nomor baris nama modul versi modul













3. Tumpukan

Anda sudah tahu apa itu stack trace , tapi apa itu stack (kelas Stack)?

Tumpukan adalah struktur data tempat Anda dapat menambahkan elemen dan dari mana Anda dapat mengambil elemen. Dengan demikian, Anda hanya dapat mengambil elemen dari akhir: pertama Anda mengambil yang terakhir ditambahkan, lalu yang kedua terakhir ditambahkan, dll.

Tumpukan nama itu sendiri menunjukkan perilaku ini, seperti bagaimana Anda berinteraksi dengan setumpuk kertas. Jika Anda meletakkan lembar 1, 2 dan 3 dalam tumpukan, Anda harus mengambilnya dalam urutan terbalik: pertama lembar ketiga, lalu lembar kedua, dan baru kemudian lembar pertama.

Java bahkan memiliki kelas koleksi Stack khusus dengan nama dan perilaku yang sama. Kelas ini berbagi banyak perilaku dengan ArrayListdan LinkedList. Tetapi ia juga memiliki metode yang menerapkan perilaku tumpukan:

Metode Keterangan
T push(T obj)
Menambahkan objelemen ke bagian atas tumpukan
T pop()
Mengambil elemen dari bagian atas tumpukan (kedalaman tumpukan berkurang)
T peek()
Mengembalikan item di bagian atas tumpukan (tumpukan tidak berubah)
boolean empty()
Memeriksa apakah koleksi kosong
int search(Object obj)
Mencari objek dalam koleksi dan mengembalikannyaindex

Contoh:

Kode Isi tumpukan (bagian atas tumpukan ada di sebelah kanan)
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]

Tumpukan cukup sering digunakan dalam pemrograman. Jadi ini adalah koleksi yang berguna.



4. Menampilkan jejak tumpukan selama penanganan pengecualian

Mengapa daftar pemanggilan metode disebut stack trace ? Karena jika Anda menganggap daftar metode sebagai tumpukan lembaran kertas dengan nama metode, maka saat Anda memanggil metode berikutnya, Anda menambahkan lembaran dengan nama metode tersebut ke tumpukan. Dan selembar kertas berikutnya berada di atasnya, dan seterusnya.

Saat sebuah metode berakhir, sheet di bagian atas tumpukan akan dihapus. Anda tidak dapat mengeluarkan lembaran dari tengah tumpukan tanpa membuang semua lembaran di atasnya. Demikian pula, Anda tidak dapat menghentikan metode di tengah rangkaian panggilan tanpa menghentikan semua metode yang telah dipanggilnya.

Pengecualian

Penggunaan lain yang menarik untuk tumpukan adalah selama penanganan pengecualian.

Saat terjadi kesalahan dalam program dan pengecualian dilemparkan , pengecualian tersebut berisi jejak tumpukan saat ini — sebuah larik yang terdiri dari daftar metode yang dimulai, dari metode utama dan diakhiri dengan metode di mana kesalahan terjadi. Bahkan ada garis di mana pengecualian dilemparkan!

Pelacakan tumpukan ini disimpan di dalam pengecualian dan dapat dengan mudah diambil darinya menggunakan metode berikut:StackTraceElement[] getStackTrace()

Contoh:

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




Tangkap pengecualian

Dapatkan jejak tumpukan yang ada saat kesalahan terjadi.

Ini adalah metode kelas Throwable, jadi semua turunannya (yakni semua pengecualian) memiliki getStackTrace()metode. Sangat nyaman, ya?

Menampilkan jejak tumpukan pengecualian

Omong-omong, Throwablekelas memiliki metode lain untuk bekerja dengan pelacakan tumpukan, metode yang menampilkan semua informasi pelacakan tumpukan yang disimpan di dalam pengecualian. Itu disebut printStackTrace().

Cukup nyaman, Anda dapat menyebutnya dengan pengecualian apa pun.

Contoh:

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