JavaRush /Blog Java /Random-MS /Stack Trace dan dengan apa ia dimakan
Alukard
Tahap
London

Stack Trace dan dengan apa ia dimakan

Diterbitkan dalam kumpulan
Dalam artikel ini, anda akan mempelajari dan memahami cara fenomena Java StackTrace, juga dikenali sebagai Panggilan Stack Tracing, berfungsi. Maklumat ini telah distrukturkan untuk pemula yang menemui konsep ini pada permulaan Java Syntax Level 9. Saya rasa anda semua, sekurang-kurangnya sekali, telah mengalami ralat yang sama semasa bekerja dalam IDE anda, tidak kira sama ada Idea , Eclipse atau sesuatu yang lain.
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 anda duga, adalah pengesanan kami. Tetapi jangan tergesa-gesa untuk panik, sekarang kami akan memecahkan contoh ini untuk anda. Mula-mula anda perlu memahami hakikat bahawa ia StackTraceberfungsi seperti Стэкnamanya. Pada ketika ini kita akan membincangkan dengan lebih terperinci. Cara koleksi Stack berfungsi Pada peringkat kelapan, anda telah pun mengenali koleksi dan mengetahui bahawa ia dibahagikan kepada tiga kumpulan Set- set, List- senarai, Map- kamus (atau peta). Menurut JavaRush (c). Kami Stackadalah sebahagian daripada kumpulan List. Prinsip operasinya boleh digambarkan sebagai LIFO , yang bermaksud Terakhir Masuk Dahulu. Iaitu, ini adalah senarai yang serupa dengan timbunan buku; untuk mengambil elemen yang kami masukkan Stackdahulu, kami perlu mengekstrak semua elemen yang kami tambahkan pada senarai kami dahulu selepas itu. Seperti yang ditunjukkan dalam gambar di atas, tidak seperti, sebagai contoh, senarai biasa ArrayListdi mana kita boleh mendapatkan sebarang elemen daripada senarai mengikut indeks. Sekali lagi untuk pengukuhan. Mendapatkan elemen dari Стэкаhanya mungkin dari akhir! Walaupun elemen pertama yang ditambahkan padanya adalah pada permulaan (atau di bahagian bawah, seperti yang lebih mudah). Ini ialah kaedah yang ada pada Stack Objek kami push()- Menambah elemen pada bahagian atas timbunan. Objek pop()- Mengembalikan elemen di bahagian atas timbunan, mengeluarkannya dalam proses. Objek peek()- Mengembalikan elemen di bahagian atas tindanan, tetapi tidak mengeluarkannya. int search()- Mencari elemen pada timbunan. Jika ditemui, ofsetnya dari bahagian atas tindanan dikembalikan. Jika tidak -1 dikembalikan. boolean empty()- Semak sama ada tindanan kosong. Mengembalikan benar jika tindanan kosong. Mengembalikan palsu jika tindanan mengandungi elemen. Jadi mengapa anda Javamemerlukannya StackTracedibina berdasarkan prinsip operasi Stack? Mari kita lihat contoh ralat di bawah yang berlaku semasa pelaksanaan program yang begitu mudah.
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 mempunyai kelas Testdengan dua kaedah. Semua orang sudah biasa maindan convertStringToIntlogiknya adalah untuk menukar dan mengembalikan rentetan yang diterima dari luar (iaitu daripada kaedah main) kepada nombor integer jenis int. Seperti yang anda lihat, kami sengaja melepasi parameter dan bukannya rentetan dengan beberapa nombor null. Kaedah kami tidak dapat memproses parameter ini dengan betul dan menyebabkan ralat NumberFormatException. Seperti yang anda ketahui, program mula menyelesaikan kerjanya dari kaedah maindan pada masa ini ia mencipta yang baru Стэкdengan nama StackTracedi mana ia meletakkan nilai semasa kerjanya di bawah nombor 1 , kemudian kita pergi ke kaedah convertStringToIntdan program sekali lagi memasukkan parameter lokasi kita ke dalam yang dibuat sebelum ini StackTracedi bawah nombor 2 , maka ia dipanggil kaedah yang tidak dapat dilihat oleh mata kita parseIntyang terletak di dalam kelas Integerdan ini sudah menjadi elemen nombor 3 kita StackTrace, dalam kaedah ini akan ada satu lagi panggilan dalaman yang ditambah ke StackTracenombor 4 untuk menyemak elemen untuk null yang akan membawa kepada ralat. Program ini perlu memaparkan ralat kami yang menunjukkan keseluruhan rantaian peralihan kami sehingga ralat itu berlaku. Di sinilah yang dibuat sebelum ini dengan data peralihan kami datang untuk 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 ralat berlaku, program pergi jauh ke dalam kaedah, tetapi sebaik sahaja ralat berlaku, segala-galanya mula berlaku dalam susunan terbalik. Baris yang menerangkan masalah dicetak (No. 1 dalam contoh), kemudian nilai terakhir (dan di atas) yang ditambah kepada kami diambil, Стэкia adalah nombor empat dan dicetak ke konsol (No. 2 dalam contoh) dan kita melihat bahawa masalah timbul dalam kelas Integerpada 614 baris kod dan memanggil baris ini, baris 770 kaedah parseIntkelas yang sama (No. 3 dalam contoh) yang, apabila ditambah kepada, Стэкadalah nombor tiga dan kaedah kelas ini, Integermasih tidak kelihatan kepada kami, telah dipanggil oleh kaedah kami convertStringToIntyang terletak pada baris 10 program kami (No. 4 dalam contoh, dan apabila menambah ia adalah kedua), dan ia, seterusnya, dipanggil mainpada baris 6 (No. 5 dalam contoh, dan apabila menambah, masing-masing, yang pertama). Jadi, dengan menyimpan Стекkaedah yang dipanggil kami langkah demi langkah, kami dapat kembali ke mainpencetakan selari maklumat yang betul-betul membawa kami kepada ralat. Tetapi StackTraceini bukan sahaja berfungsi dengan ralat, ia membolehkan kami mendapatkan banyak maklumat menarik tentang proses permohonan kami. Mari kita lihat satu lagi contoh popular dalam ulasan untuk kuliah utama tahap 9. Kami mempunyai kod dan saya akan segera melampirkan gambar padanya yang menggambarkan 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());
        }
    }
}
Jejak Timbunan dan dengan apa ia dimakan - 2 Di sini program kami menjalankan tugasnya dengan sempurna dan berakhir. Inilah yang akan kita lihat dalam output konsol:
getStackTrace
method5
method4
method2
main

Process finished with exit code 0
Bagaimanakah kita mendapat kesimpulan ini dan apa yang berlaku dalam kaedah kelima, bermula dari baris 20? Saya takut yang terbaik yang boleh saya lakukan ialah menambah penjelasan paling popular (disingkatkan) oleh pengguna Kirill daripada komen ke kuliah. Mari kita beralih kepada baris penciptaan StackTracedan menganalisisnya unsur demi unsur:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]- petunjuk jenis tatasusunan (Pada peringkat awal anda sudah mengetahui tentang tatasusunan seperti int[], String[], di sini ia adalah sama). stackTraceElements- nama tatasusunan boleh menjadi apa sahaja, dengan mengambil kira peraturan penamaan umum, ini tidak menjejaskan kerja. Thread.currentThread()- mendapatkan pautan ke utas semasa di mana kaedah yang kami ingin jejak dilaksanakan (buat masa ini ini tidak penting, anda akan menganalisis benang dengan lebih terperinci pada tahap 16 dalam pencarian Java Core) getStackTrace()- kami mendapat semua Стэкkaedah yang dipanggil (Ini adalah pengambil biasa untuk StackTrace) Sekarang mari kita lihat apakah Tatasusunan yang dicipta mungkin berguna kepada kita. Kami memahami bahawa tatasusunan menyimpan maklumat tentang kaedah yang dilaksanakan. (c) Dan untuk ini, dalam baris ke-21, kami melancarkan kitaran diubah suai foryang dipanggil forEach(dengan cara ini, bagi mereka yang belum mempelajari kitaran ini, saya menasihati anda untuk membaca tentangnya) dan mengeluarkan data dari tatasusunan ke konsol , iaitu maklumat tentang kaedah yang telah dilaksanakan semasa kerja menggunakan pembinaan element.getMethodName(). Perhatian, seperti yang kita lihat, elemen sifar tatasusunan ternyata menjadi dirinya sendiri getStackTrace(), kerana pada saat menerima tatasusunan data itu adalah kaedah terakhir yang dilaksanakan dan dengan itu berakhir di bahagian atas Стэка, dan mengingati pembinaan kami " Masuk terakhir, keluar dahulu ” adalah serta-merta yang pertama ditambahkan pada tatasusunan di bawah unsur sifar. Inilah perkara lain yang boleh kita perolehi daripada StackTraceElement: String getClassName()- Mengembalikan nama kelas. String getMethodName()- Mengembalikan nama kaedah. String getFileName()- Mengembalikan nama fail (boleh terdapat banyak kelas dalam satu fail). String getModuleName()- Mengembalikan nama modul (boleh batal). String getModuleVersion()- Mengembalikan versi modul (boleh batal). int getLineNumber()- Mengembalikan nombor baris dalam fail di mana kaedah itu dipanggil. Sekarang setelah anda memahami prinsip umum operasi, saya menasihati anda untuk mencuba sendiri kaedah yang berbeza StackTracedalam Ide anda . Walaupun anda belum menguasai segala-galanya sepenuhnya, teruskan belajar dan teka-teki akan berubah dengan cara yang sama berlaku untuk saya dalam perkara ini. Saya doakan anda semua berjaya! Ps Jika anda menyukai bahan ini, sila sokong dengan suka. Ia tidak sukar untuk anda, saya redha. Terima kasih dan jumpa anda di tahap 41 ;)
Komen
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION