Pada artikel ini, Anda akan mempelajari dan memahami cara kerja fenomena Java StackTrace, juga dikenal sebagai Call Stack Tracing. Informasi ini disusun untuk pemula yang menemukan konsep ini di awal Sintaks Java Level 9. Saya rasa Anda semua, setidaknya sekali, pernah mengalami kesalahan serupa saat bekerja di IDE Anda, terlepas dari apakah itu Idea , Eclipse , atau yang lainnya.
Exception in thread "main" java.lang.ArithmeticException
at com.example.task01.Test.division(Test.java:10)
at com.example.task01.Test.main(Test.java:6)
Ini, seperti yang sudah Anda duga, adalah penelusuran kami. Namun jangan terburu-buru panik, sekarang kami akan menguraikan contoh ini untuk Anda. Pertama, Anda perlu memahami fakta bahwa ini StackTrace
berfungsi sesuai dengan Стэк
namanya. Pada titik ini kita akan membahas lebih detail. Pada tingkat kedelapan, Anda telah mengenal koleksi dan mengetahui bahwa koleksi tersebut dibagi menjadi tiga kelompok Set
- kumpulan, List
- daftar, Map
- kamus (atau peta). Menurut JavaRush (c). Kami Stack
adalah bagian dari grup List
. Prinsip pengoperasiannya dapat digambarkan sebagai LIFO , yang merupakan singkatan dari Last In First Out. Yakni, ini adalah daftar yang mirip dengan tumpukan buku; untuk mengambil elemen yang kita masukkan terlebih Stack
dahulu, kita perlu mengekstrak terlebih dahulu semua elemen yang kita tambahkan ke daftar setelahnya. Seperti yang ditunjukkan pada gambar di atas, tidak seperti, misalnya, daftar biasa ArrayList
di mana kita bisa mendapatkan elemen apa pun dari daftar berdasarkan indeks. Sekali lagi untuk penguatan. Mendapatkan elemen Стэка
hanya mungkin dilakukan dari akhir! Sedangkan elemen pertama yang ditambahkan ke dalamnya ada di awal (atau di bawah, mana yang lebih nyaman). Ini adalah metode yang dimiliki Stack
Objek kita push()
- Menambahkan elemen ke bagian atas tumpukan. Objek pop()
- Mengembalikan elemen di bagian atas tumpukan, menghapusnya dalam proses. Objek peek()
- Mengembalikan elemen di bagian atas tumpukan, namun tidak menghapusnya. int search()
- Mencari elemen di tumpukan. Jika ditemukan, offsetnya dari atas tumpukan dikembalikan. Jika tidak -1 dikembalikan. boolean empty()
- Memeriksa apakah tumpukan kosong. Mengembalikan nilai benar jika tumpukan kosong. Mengembalikan nilai salah jika tumpukan berisi elemen. Jadi mengapa Anda Java
memerlukan StackTrace
yang dibangun berdasarkan prinsip pengoperasian Stack
? Mari kita lihat contoh kesalahan di bawah ini yang terjadi selama eksekusi program sederhana tersebut.
public class Test {
public static void main(String[] args) {
System.out.println(convertStringToInt(null));
}
public static int convertStringToInt(String s) {
int x = Integer.parseInt(s);
return x;
}
}
Kami memiliki kelas Test
dengan dua metode. Semua orang sudah familiar main
dan convertStringToInt
logikanya adalah mengubah dan mengembalikan string yang diterima dari luar (yaitu dari metode main
) menjadi bilangan bulat bertipe int
. Seperti yang Anda lihat, kami sengaja meneruskan parameter alih-alih string dengan nomor tertentu null
. Metode kami tidak dapat memproses parameter ini dengan benar dan menyebabkan kesalahan NumberFormatException
. Seperti yang Anda ketahui, program mulai mengerjakan pekerjaannya dari metode main
dan pada saat ini ia membuat yang baru Стэк
dengan nama StackTrace
yang menempatkan nilai pekerjaannya saat ini di bawah nomor 1 , lalu kita beralih ke metode convertStringToInt
dan program lagi memasukkan parameter lokasi kita ke dalam yang dibuat sebelumnya StackTrace
di bawah nomor 2 , kemudian disebut metode yang tidak terlihat oleh mata kita parseInt
yang terletak di kelas Integer
dan ini sudah menjadi elemen nomor 3 kita StackTrace
, dalam metode ini akan ada panggilan internal lain yang ditambahkan ke StackTrace
nomor 4 untuk memeriksa elemen untuk null yang akan menyebabkan kesalahan. Program perlu menampilkan kesalahan kita yang menunjukkan seluruh rantai transisi kita hingga kesalahan terjadi. Di sinilah yang sebelumnya dibuat dengan data transisi kita datang membantunya StackTrace
.
Exception in thread "main" java.lang.NumberFormatException: null
at java.base/java.lang.Integer.parseInt(Integer.java:614)
at java.base/java.lang.Integer.parseInt(Integer.java:770)
at com.example.task01.Test.convertStringToInt(Solution.java:10)
at com.example.task01.Test.main(Solution.java:6)
Sebelum kesalahan terjadi, program mendalami metodenya, tetapi segera setelah kesalahan terjadi, semuanya mulai terjadi dalam urutan terbalik. Sebuah baris yang menggambarkan masalah dicetak (No. 1 dalam contoh), kemudian nilai terakhir (dan di atas) yang ditambahkan ke nilai kita diambil, Стэк
itu adalah nomor empat dan dicetak ke konsol (No. 2 dalam contoh) dan kita melihat bahwa masalah muncul di kelas Integer
pada baris kode 614 dan disebut baris ini, baris 770 dari metode parseInt
kelas yang sama (No. 3 dalam contoh) yang, jika ditambahkan, Стэк
adalah nomor tiga dan metode kelas ini, Integer
masih belum terlihat oleh kami, sudah dipanggil dengan metode kami convertStringToInt
yang terletak di baris 10 program kami (No. 4 dalam contoh, dan ketika ditambahkan adalah yang kedua), dan, pada gilirannya, dipanggil main
di baris 6 (No. 5 dalam contoh, dan saat menambahkan, masing-masing, yang pertama). Jadi, dengan menyimpan Стек
metode yang kami panggil selangkah demi selangkah, kami dapat kembali ke main
pencetakan informasi paralel yang justru membawa kami ke kesalahan tersebut. Tapi StackTrace
ini tidak hanya mengatasi kesalahan, ini memungkinkan kita mendapatkan banyak informasi menarik tentang proses aplikasi kita. Mari kita lihat contoh populer lainnya di komentar kuliah utama level 9. Kami memiliki kodenya dan saya akan segera melampirkan gambar yang memvisualisasikan proses program:
public class Test {
public static void main(String[] args) {
method1();
method2();
}
public static void method1() {
//не вызывает ничего
}
public static void method2() {
method3();
method4();
}
public static void method3() {
//не вызывает ничего
}
public static void method4() {
method5();
}
public static void method5() {
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for (StackTraceElement element:stackTraceElements) {
System.out.println(element.getMethodName());
}
}
}
Di sini program kami melakukan tugasnya dengan sempurna dan berakhir. Inilah yang akan kita lihat di keluaran konsol:
getStackTrace
method5
method4
method2
main
Process finished with exit code 0
Bagaimana kita mendapatkan kesimpulan ini dan apa yang terjadi pada metode kelima, dimulai dari baris 20? Saya khawatir hal terbaik yang bisa saya lakukan adalah menambahkan penjelasan paling populer (disingkat) oleh pengguna Kirill dari komentar hingga kuliah. Mari kita beralih ke garis pembuatan StackTrace
dan menganalisisnya elemen demi elemen:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]
- indikasi tipe array (Pada level awal Anda sudah mempelajari tentang array seperti int[], String[], ini sama). stackTraceElements
- nama array bisa apa saja, dengan mempertimbangkan aturan penamaan umum, ini tidak mempengaruhi pekerjaan. Thread.currentThread()
- mendapatkan tautan ke utas saat ini di mana metode yang ingin kami lacak dijalankan (untuk saat ini ini tidak penting, Anda akan menganalisis utas secara lebih rinci di level 16 dalam pencarian Java Core) getStackTrace()
- kami mendapatkan semua Стэк
metode yang disebut (Ini adalah pengambil reguler untuk StackTrace
) Sekarang mari kita lihat apa yang Array yang dibuat mungkin berguna bagi kita. Kami memahami bahwa array menyimpan informasi tentang metode yang dieksekusi. (c) Dan untuk ini, di baris ke-21, kami meluncurkan siklus yang dimodifikasi for
yang disebut forEach
(omong-omong, bagi mereka yang belum mempelajari siklus ini, saya menyarankan Anda untuk membacanya) dan mengeluarkan data dari array ke konsol , yaitu informasi tentang metode apa yang dilakukan selama pekerjaan menggunakan konstruksi element.getMethodName()
. Perhatian, seperti yang kita lihat, elemen nol dari array ternyata adalah dirinya sendiri, getStackTrace()
karena pada saat menerima array data, itu adalah metode terakhir yang dieksekusi dan dengan demikian berakhir di atas Стэка
, dan mengingat konstruksi kita “ Masuk terakhir, keluar pertama ” adalah yang pertama ditambahkan ke array di bawah elemen nol. Inilah hal lain yang bisa kita dapatkan dari StackTraceElement
: String getClassName()
- Mengembalikan nama kelas. String getMethodName()
- Mengembalikan nama metode. String getFileName()
- Mengembalikan nama file (ada banyak kelas dalam satu file). String getModuleName()
- Mengembalikan nama modul (bisa null). String getModuleVersion()
- Mengembalikan versi modul (bisa null). int getLineNumber()
- Mengembalikan nomor baris dalam file tempat metode dipanggil. Sekarang setelah Anda memahami prinsip umum pengoperasiannya, saya menyarankan Anda untuk mencoba sendiri berbagai metode StackTrace
di Ide Anda . Bahkan jika Anda belum sepenuhnya menguasai semuanya, teruslah belajar dan teka-teki itu akan menjadi sama seperti yang saya alami dalam hal ini. Saya berharap Anda semua sukses! Ps Jika Anda menyukai materi ini, mohon dukung dengan suka. Itu tidak sulit bagimu, aku senang. Terima kasih dan sampai jumpa di level 41 ;)
GO TO FULL VERSION