JavaRush /Java блогы /Random-KK /Stack Trace және ол немен жейді
Alukard
Деңгей
London

Stack Trace және ол немен жейді

Топта жарияланған
Бұл мақалада сіз Call Stack Tracing деп аталатын Java феномені StackTrace қалай жұмыс істейтінін біліп, түсінесіз. Бұл ақпарат Java синтаксисінің 9-деңгейінің басында осы концепцияға тап болған жаңадан бастаушыларға арналған. Менің ойымша, сіздердің барлығыңыз кем дегенде бір рет IDE-де жұмыс істегенде, Idea , Eclipse немесе басқа нәрсе болғанына қарамастан, ұқсас қателерге тап болдыңыз .
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)
Бұл, сіз болжағандай, біздің іздеуіміз. Бірақ дүрбелеңге асықпаңыз, енді біз сіз үшін бұл мысалды талдаймыз. StackTraceАлдымен сіз оның аты айтып тұрғандай жұмыс істейтінін түсінуіңіз керек Стэк. Бұл жерде біз аздап толығырақ тоқталамыз. Stack жинағы қалай жұмыс істейді Сегізінші деңгейде сіз жинақтармен танысып, олардың үш топқа бөлінгенін білесіз Set- жиынтық, List- тізім, Map- сөздік (немесе карта). JavaRush (c) бойынша . Біздің Stackтоптың бір бөлігі List. Оның жұмыс істеу принципін LIFO деп сипаттауға болады, ол «Соңғы кіріс бірінші шығыс» дегенді білдіреді . Атап айтқанда, бұл кітаптар дестесіне ұқсас тізім; біз Stackбірінші енгізген элементті алу үшін алдымен тізімге кейін қосқан барлық элементтерді шығарып алуымыз керек. Жоғарыдағы суретте көрсетілгендей, мысалы, ArrayListтізімнен кез келген элементті индекс бойынша алуға болатын кәдімгі тізімнен айырмашылығы. Тағы бір рет күшейту үшін. Элементті алу Стэкатек соңына дейін мүмкін! Оған қосылған бірінші элемент басында (немесе төменгі жағында, ыңғайлырақ). Stack Бұл біздің нысанда бар әдістер push()- стектің жоғарғы жағына элемент қосады. Нысан pop()- процесте оны жоя отырып, стектің жоғарғы жағындағы элементті қайтарады. Нысан peek()- стектің жоғарғы жағындағы элементті қайтарады, бірақ оны жоймайды. int search()- стектегі элементті іздейді. Егер табылса, оның стектің жоғарғы жағынан ығысуы қайтарылады. Әйтпесе -1 қайтарылады. логикалық empty()- стектің бос екенін тексереді. Стек бос болса, шын мәнін қайтарады. Стекте элементтер болса, жалған мәнін қайтарады. Неліктен сізге жұмыс принциптеріне негізделген құрылғы Javaқажет ? Төмендегі осындай қарапайым бағдарламаны орындау кезінде орын алған қатенің мысалын қарастырайық. 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;
    }
}
TestБізде екі әдіс бар сынып бар . Барлығына таныс mainжәне convertStringToIntоның логикасы сырттан (дәлірек айтқанда әдістен main) алынған жолды түрдегі бүтін санға түрлендіру және қайтару болып табылады int. Көріп отырғаныңыздай, біз кейбір саны бар жолдың орнына параметрді әдейі жібердік null. Біздің әдіс бұл параметрді дұрыс өңдей алмады және қателік туғызды NumberFormatException. Өздеріңіз білетіндей, бағдарлама өз жұмысын әдіспен өңдеуді бастайды mainжәне осы сәтте ол өз жұмысының ағымдағы мәнін 1Стэк санының астына қоятын атауы бар жаңасын жасайды, содан кейін әдіс пен бағдарламаға қайта барамыз. біздің орналасқан жеріміздің параметрлерін бұрын жасалған 2 санына енгізеді, содан кейін ол сыныпта орналасқан көзге көрінбейтін әдіс деп аталады және бұл біздің №3 элемент болады , бұл әдісте тағы бір ішкі қоңырау қосылады. қатеге әкелетін элементті нөлге тексеру үшін 4 санына . Бағдарлама қате орын алғанша біздің өтулеріміздің бүкіл тізбегін көрсететін қатені көрсетуі керек. Дәл осы жерде оған көмекке біздің ауысуларымыздың деректерімен бұрын жасалған . 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)
Қате орын алмас бұрын бағдарлама әдістерге тереңірек үңілді, бірақ қате орын алған бойда бәрі кері тәртіпте бола бастайды. Мәселені сипаттайтын жол басып шығарылады (мысалдағы №1), содан кейін бізге қосылған соңғы (және жоғарғы жағында) мән алынады, Стэкол төртінші нөмір болды және консольге басып шығарылады (мысалдағы № 2) және біз мәселе codeтың 614 жолындағы сыныпта туындағанын Integerжәне осы жолды, сол класс әдісінің 770 жолы деп атағанын көреміз parseInt(мысалдағы №3), ол қосылған кезде Стэкүшінші нөмір болды және осы класс әдісі, Integerәлі де бізге көрінбейді, біздің бағдарламамыздың 10-жолында орналасқан әдісімізбен шақырылды convertStringToInt(мысалдағы №4, ал қосу кезінде екінші болды), ал ол өз кезегінде main6-жолда (No5-те) шақырылды. мысал және қосу кезінде, тиісінше, бірінші). Осылайша, шақырылған әдістерді кезең-кезеңмен сақтау арқылы біз қателікке әкелген ақпаратты параллель басып шығаруға Стекқайта оралдық . mainБірақ StackTraceбұл қателермен жұмыс істеу ғана емес, ол бізге біздің қолдану процесі туралы көптеген қызықты ақпаратты алуға мүмкіндік береді. 9-деңгейдегі негізгі дәріске түсініктемелерде тағы бір танымал мысалды қарастырайық. Бізде code бар және мен оған бағдарламаның процесін визуализациялайтын суретті дереу қосамын:
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 және оны немен жейді - 2 Міне, біздің бағдарлама өз жұмысын мінсіз атқарып, аяқталады. Бұл консоль шығысында көретініміз:
getStackTrace
method5
method4
method2
main

Process finished with exit code 0
Бұл қорытындыға қалай келдік және 20-жолдан бастап бесінші әдісте не болды? Мен жасай алатын ең жақсы нәрсе - дәріске түсініктемелерден Кирилл қолданушысының ең танымал түсіндірмесін (қысқартылған) қосу деп қорқамын. Жасау жолына бұрылып StackTrace, оны элемент бойынша талдаймыз:
StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
StackTraceElement[]- массив түрінің көрсеткіші (Алғашқы деңгейлерде сіз int[], String[] сияқты массивтер туралы бұрыннан білдіңіз, мұнда бәрі бірдей). stackTraceElements- жалпы атау ережелерін ескере отырып, массивтің атауы кез келген нәрсе болуы мүмкін, бұл жұмысқа әсер етпейді. Thread.currentThread()- біз қадағалағымыз келетін әдістер орындалатын ағымдағы ағынға сілтеме алу (әзірше бұл маңызды емес, сіз Java Core квестінде 16-деңгейдегі ағындарды толығырақ талдайсыз) getStackTrace()- біз барлық Стэкшақырылған әдістерді аламыз (Бұл - үшін кәдімгі қабылдаушы StackTrace) Енді жасалған массив бізге не пайдалы болуы мүмкін екенін көрейік. Жиым орындалған әдістер туралы ақпаратты сақтайтынын түсінеміз. (c) Бұл үшін 21-ші жолда біз өзгертілген циклды іске қосамыз ( forайтпақшы forEach, бұл циклды әлі зерттемегендер үшін бұл туралы оқуға кеңес беремін) және массивтен консольге деректерді шығарамыз. , дәлірек айтқанда, құрылысты пайдалана отырып, жұмыс барысында қандай әдістер орындалғаны туралы ақпарат element.getMethodName(). Назар аударыңыз, біз көріп отырғанымыздай, массивтің нөлдік элементі сәйкесінше өзі болып шықты getStackTrace(), өйткені деректер массивін алу сәтінде бұл орындалған соңғы әдіс болды және осылайша жоғарғы жағында аяқталды Стэка, және біздің құрылысымызды есте сақтаймыз « Соңғы кірген, бірінші шыққан » бірден нөл элементінің астындағы массивке бірінші қосылатын болады. Мына жерден тағы не алуға болады StackTraceElement: Жол getClassName()– сыныптың атын қайтарады. Жол getMethodName()– әдіс атын қайтарады. Жол getFileName()– файл атын қайтарады (бір файлда көптеген сыныптар болуы мүмкін). Жол getModuleName()– модуль атын қайтарады (нөл болуы мүмкін). Жол getModuleVersion()– модуль нұсқасын қайтарады (нөл болуы мүмкін). int getLineNumber()- әдіс шақырылған файлдағы жол нөмірін қайтарады. Енді сіз жұмыс істеудің жалпы принципін түсіндіңіз, мен сізге IdeStackTrace -де әртүрлі әдістерді өзіңіз қолданып көруге кеңес беремін . Сіз бәрін толық меңгермеген болсаңыз да, оқуды жалғастырыңыз және басқатырғыш осы мәселеде мен үшін қалай болған болса, солай болады. Барлығыңызға сәттілік тілеймін! Ps Егер сізге бұл материал ұнаса, лайк басып қолдаңыз. Сізге қиын емес, мен ризамын. Рахмет және 41-деңгейде кездескенше;)
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION