JavaRush /Java Blog /Random-ID /Stack Trace dan apa yang dimakannya
Alukard
Level 37
London

Stack Trace dan apa yang dimakannya

Dipublikasikan di grup Random-ID
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 StackTraceberfungsi sesuai dengan Стэкnamanya. Pada titik ini kita akan membahas lebih detail. Cara kerja koleksi Stack 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 Stackadalah 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 Stackdahulu, 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 ArrayListdi 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 Javamemerlukan StackTraceyang 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 Testdengan dua metode. Semua orang sudah familiar maindan convertStringToIntlogikanya 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 maindan pada saat ini ia membuat yang baru Стэкdengan nama StackTraceyang menempatkan nilai pekerjaannya saat ini di bawah nomor 1 , lalu kita beralih ke metode convertStringToIntdan program lagi memasukkan parameter lokasi kita ke dalam yang dibuat sebelumnya StackTracedi bawah nomor 2 , kemudian disebut metode yang tidak terlihat oleh mata kita parseIntyang terletak di kelas Integerdan ini sudah menjadi elemen nomor 3 kita StackTrace, dalam metode ini akan ada panggilan internal lain yang ditambahkan ke StackTracenomor 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 Integerpada baris kode 614 dan disebut baris ini, baris 770 dari metode parseIntkelas yang sama (No. 3 dalam contoh) yang, jika ditambahkan, Стэкadalah nomor tiga dan metode kelas ini, Integermasih belum terlihat oleh kami, sudah dipanggil dengan metode kami convertStringToIntyang terletak di baris 10 program kami (No. 4 dalam contoh, dan ketika ditambahkan adalah yang kedua), dan, pada gilirannya, dipanggil maindi 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 mainpencetakan informasi paralel yang justru membawa kami ke kesalahan tersebut. Tapi StackTraceini 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());
        }
    }
}
Stack Trace dan dimakan dengan apa - 2 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 StackTracedan 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 foryang 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 StackTracedi 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 ;)
Komentar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION