JavaRush /Java blogi /Random-UZ /Stack Trace va u nima bilan yeyiladi
Alukard
Daraja
London

Stack Trace va u nima bilan yeyiladi

Guruhda nashr etilgan
Ushbu maqolada siz StackTrace Java hodisasi, shuningdek Call Stack Tracing deb nomlanuvchi qanday ishlashini bilib olasiz va tushunasiz. Ushbu ma'lumot Java Sintaksis 9-darajasining boshida ushbu kontseptsiyaga duch kelgan yangi boshlanuvchilar uchun tuzilgan. O'ylaymanki, Idea , Eclipse yoki boshqa biror narsa bo'lishidan qat'i nazar, barchangiz, hech bo'lmaganda bir marta IDE-da ishlashda shunga o'xshash xatolarga duch keldingiz .
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)
Bu, siz taxmin qilganingizdek, bizning kuzatuvimiz. Ammo vahima qo'yishga shoshilmang, endi biz siz uchun ushbu misolni parchalaymiz. StackTraceAvval siz uning nomidan ko'rinib turganidek ishlashini tushunishingiz kerak Стэк. Shu nuqtada biz biroz batafsilroq to'xtalamiz. Stack kolleksiyasi qanday ishlaydi Sakkizinchi bosqichda siz allaqachon to'plamlar bilan tanishdingiz va ular uchta guruhga bo'linganligini bilasiz Set- to'plam, List- ro'yxat, Map- lug'at (yoki xarita). JavaRush (c) ga ko'ra . Bizniki Stackguruhning bir qismi List. Uning ishlash printsipini LIFO deb ta'riflash mumkin, ya'ni "Oxirgi kirish birinchi chiqish" degan ma'noni anglatadi . Ya'ni, bu kitoblar to'plamiga o'xshash ro'yxat; biz Stackbirinchi qo'ygan elementni olish uchun avval ro'yxatimizga qo'shgan barcha elementlarni ajratib olishimiz kerak. Yuqoridagi rasmda ko'rsatilganidek, masalan, oddiy ro'yxatdan farqli o'laroq, ArrayListbiz indeks bo'yicha ro'yxatdan istalgan elementni olishimiz mumkin. Yana bir bor mustahkamlash uchun. dan elementni olish Стэкаfaqat oxiridan mumkin! Unga qo'shilgan birinchi element boshida (yoki pastki qismida, qulayroq bo'lganidek). Stack Bu bizning Ob'ektimizda mavjud usullar push()- stekning yuqori qismiga element qo'shadi. Ob'ekt pop()- jarayonda uni olib tashlagan holda stekning yuqori qismidagi elementni qaytaradi. Ob'ekt peek()- stekning yuqori qismidagi elementni qaytaradi, lekin uni olib tashlamaydi. int search()- stekdagi elementni qidiradi. Agar topilsa, uning stekning yuqori qismidan siljishi qaytariladi. Aks holda -1 qaytariladi. mantiqiy empty()- stek bo'sh yoki yo'qligini tekshiradi. Agar stek bo'sh bo'lsa, true qiymatini qaytaradi. Agar stekda elementlar bo'lsa, false qiymatini qaytaradi. Xo'sh, nima uchun sizga ishlash tamoyillari asosida qurilgan qurilma Javakerak ? Quyida shunday oddiy dasturni bajarish jarayonida yuzaga kelgan xatolik misolini ko'rib chiqamiz. StackTraceStack
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;
    }
}
TestBizda ikkita usuldan iborat sinf mavjud . Hammaga tanish mainva convertStringToIntuning mantig'i tashqaridan (ya'ni usuldan main) olingan satrni butun son turiga aylantirish va qaytarishdir int. Ko'rib turganingizdek, biz ataylab ba'zi bir raqam bilan satr o'rniga parametrni o'tkazdik null. Bizning usulimiz ushbu parametrni to'g'ri qayta ishlay olmadi va xatoga sabab bo'ldi NumberFormatException. Ma'lumki, dastur o'z ishini usuldan ishlab chiqa boshlaydi mainva ayni paytda u o'z ishining joriy qiymatini 1Стэк raqami ostiga qo'yadigan nom bilan yangisini yaratadi, keyin biz yana usul va dasturga o'tamiz. bizning joylashuvimiz parametrlarini 2 raqami ostida avval yaratilganiga kiritadi , keyin u sinfda joylashgan bizning ko'zimizga ko'rinmas usul deb ataladi va bu allaqachon bizning 3- sonli elementimiz bo'ladi , bu usulda yana bir ichki qo'ng'iroq qo'shiladi. elementni null uchun tekshirish uchun 4 raqamiga xatolikka olib keladi. Dastur xato sodir bo'lgunga qadar bizning o'tishlarimizning butun zanjirini ko'rsatadigan xatoimizni ko'rsatishi kerak. Bu erda bizning o'tishlarimiz ma'lumotlari bilan ilgari yaratilgan narsa unga yordamga keladi . StackTraceconvertStringToIntStackTraceparseIntIntegerStackTraceStackTraceStackTrace
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)
Xato yuz berishidan oldin dastur usullarga chuqur kirib bordi, lekin xatolik yuzaga kelishi bilanoq hamma narsa teskari tartibda sodir bo'la boshlaydi. Muammoni tavsiflovchi satr chop etiladi (misolda 1-son), so'ngra biznikiga qo'shilgan oxirgi (va yuqorida) qiymat olinadi, Стэкu to'rtinchi raqam edi va konsolga chop etiladi (misolda № 2) va biz muammo Integer614 kod satrida sinfda paydo bo'lganligini ko'ramiz va bu satr, xuddi shu sinfga (misolda № 3) 770-satrga parseIntqo'shilganda Стэкuchinchi raqam bo'lgan va bu sinf usuli deb nomlangan. hali bizga ko'rinmas, dasturimizning 10-qatorida joylashgan Integerusulimiz bilan chaqirilgan (misolda 4-raqam, qo'shilganda esa ikkinchi bo'lgan) va u o'z navbatida 6-qatorda (5-sonli) chaqirilgan. misol va qo'shganda, mos ravishda, birinchi). Shunday qilib, chaqirilgan usullarni bosqichma-bosqich saqlash orqali biz xatoga olib kelgan ma'lumotlarni parallel chop etishga qaytishga muvaffaq bo'ldik . Ammo bu nafaqat xatolar bilan ishlash, balki bizning arizamiz jarayoni haqida juda ko'p qiziqarli ma'lumotlarni olish imkonini beradi. Keling, 9-darajali asosiy ma'ruza sharhlarida yana bir mashhur misolni ko'rib chiqaylik. Bizda kod bor va men darhol unga dastur jarayonini aks ettiruvchi rasmni qo'shaman: convertStringToIntmainСтекmainStackTrace
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 va u nima bilan iste'mol qilinadi - 2 Mana bizning dasturimiz o'z ishini beg'ubor bajaradi va tugaydi. Konsol chiqishida biz buni ko'ramiz:
getStackTrace
method5
method4
method2
main

Process finished with exit code 0
Qanday qilib biz bu xulosaga keldik va 20-qatordan boshlab beshinchi usulda nima sodir bo'ldi? Qo'rqamanki, men qila oladigan eng yaxshi narsa - Kirill foydalanuvchisi tomonidan ma'ruzaga sharhlardan eng mashhur tushuntirishni (qisqartirilgan) qo'shish. Keling, yaratilish chizig'iga o'taylik StackTraceva uni element bo'yicha tahlil qilamiz:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]- massiv turini ko'rsatish (Ilk bosqichlarda siz int[], String[] kabi massivlar haqida allaqachon bilib oldingiz, bu erda ham xuddi shunday). stackTraceElements- massivning nomi har qanday bo'lishi mumkin, umumiy nomlash qoidalarini hisobga olgan holda, bu ishga ta'sir qilmaydi. Thread.currentThread()- biz kuzatmoqchi bo'lgan usullar bajariladigan joriy mavzuga havolani olish (hozircha bu muhim emas, siz Java Core kvestida 16-darajada mavzularni batafsil tahlil qilasiz) getStackTrace()- biz barcha Стэкchaqirilgan usullarni olamiz. (Bu oddiy qabul qiluvchi StackTrace) Endi yaratilgan massiv biz uchun nima foydali bo'lishi mumkinligini ko'rib chiqamiz. Biz tushunamizki, massiv bajarilgan usullar haqidagi ma'lumotlarni saqlaydi. (c) Va buning uchun 21-qatorda biz o'zgartirilgan tsiklni ishga tushiramiz ( foraytmoqchi forEach, bu tsiklni hali o'rganmaganlar uchun bu haqda o'qishni maslahat beraman) va massivdan konsolga ma'lumotlarni chiqaramiz. , ya'ni qurilish yordamida ish paytida qanday usullar bajarilganligi haqida ma'lumot element.getMethodName(). Diqqat, biz ko'rib turganimizdek, massivning nol elementi mos ravishda o'zi bo'lib chiqdi getStackTrace(), chunki ma'lumotlar massivini qabul qilish paytida u bajarilgan va shu bilan yuqorida joylashgan oxirgi usul edi Стэкаva bizning qurilishimizni esladi " Oxirgi kir, birinchi chiqadi ” darhol nol element ostida massivga birinchi qo‘shiladi. dan yana nimani olishimiz mumkin StackTraceElement: String getClassName()- sinf nomini qaytaradi. String getMethodName()- usul nomini qaytaradi. String getFileName()- fayl nomini qaytaradi (bitta faylda ko'p sinflar bo'lishi mumkin). String getModuleName()- modul nomini qaytaradi (null bo'lishi mumkin). String getModuleVersion()- modul versiyasini qaytaradi (null bo'lishi mumkin). int getLineNumber()- Usul chaqirilgan fayldagi satr raqamini qaytaradi. Endi siz ishlashning umumiy tamoyilini tushunganingizdan so'ng, men o'zingizning Ideingizda turli usullarni sinab ko'rishingizni maslahatStackTrace beraman . Agar siz hamma narsani to'liq o'zlashtirmagan bo'lsangiz ham, o'rganishni davom eting va jumboq bu masalada men uchun qanday bo'lsa, xuddi shunday bo'ladi. Barchangizga muvaffaqiyatlar tilayman! Ps Agar sizga ushbu material yoqqan bo'lsa, iltimos, uni like bosib qo'llab-quvvatlang. Siz uchun qiyin emas, mamnunman. Rahmat va 41-darajada ko'rishguncha;)
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION