JavaRush /Java блогу /Random-KY /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()- Стектин жогору жагындагы элементти кайтарат, бирок аны алып салbyte. int search()- стектен элементти издейт. Эгер табылса, анын стектин жогору жагындагы жылышуусу кайтарылат. Болбосо -1 кайтарылат. логикалык empty()- Стек бош экенин текшерет. Стек бош болсо, чындыкты кайтарат. Стек элементтерди камтыса, false кайтарат. Анда эмне үчүн сизге иштөө принциптерине негизделген бири 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жана ушул учурда ал жаңысын түзөт, Стэканда StackTraceал өзүнүн ишинин учурдагы маанисин 1- сандын астына коет , андан кийин биз методго convertStringToIntжана программага кайра өтөбүз. биздин жайгашкан жерибиздин параметрлерин 2-StackTrace санында мурда түзүлгөнгө киргизет , андан кийин ал класста жайгашкан биздин көзүбүзгө көрүнбөгөн метод деп аталат жана бул биздин №3 элемент болот , бул ыкмада дагы бир ички чалуу кошулат. Катага алып келе турган элементти нөлгө текшерүү үчүн 4 -санга . Программа ката пайда болгонго чейин өткөөлдөрдүн бүт чынжырын көрсөтүү менен биздин катаны көрсөтүшү керек. Бул жерде буга чейин биздин өткөөлдөрдүн маалыматтары менен түзүлгөн нерсе жардамга келет . parseIntIntegerStackTraceStackTraceStackTrace
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) жана биз көйгөй Integercodeдун 614-сапында класста пайда болгонун жана ушул сап деп аталган ошол эле класстын ыкмасынын 770-сапын parseInt(мисалы №3) көрүп жатабыз, ал кошулганда Стэкүчүнчү номер болгон жана бул класс ыкмасы, Integerбизге дагы деле көрүнбөй, биздин программабыздын 10-сапында жайгашкан методубуз менен чакырылган convertStringToInt(мисалы №4, ал эми кошууда экинчи болгон) жана ал өз кезегинде main6-сапта (№5-жылы) чакырылган. мисал, жана кошууда, тиешелүүлүгүнө жараша, биринчи). Ошентип, биздин чакырылган ыкмаларды этап-этабы менен сактоо менен , биз так катага алып келген маалыматты параллелдүү басып чыгарууга Стеккайтып келе алдык . 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 Бул жерде биздин программа өз ишин кемчorксиз аткарып бүтөт. Бул консолдун жыйынтыгында көрө турган нерсе:
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: String getClassName()- Класстын атын кайтарат. Стринг getMethodName()- методдун атын кайтарат. Стринг getFileName()- файлдын атын кайтарат (бир файлда көптөгөн класстар болушу мүмкүн). Стринг getModuleName()- модулдун атын кайтарат (нөл болушу мүмкүн). Стринг getModuleVersion()- модулдун versionсын кайтарат (нөл болушу мүмкүн). int getLineNumber()- Метод чакырылган файлдагы саптын номерин кайтарат. Эми сиз иштөөнүн жалпы принцибин түшүнгөнүңүздөн кийин, мен сизге өзүңүздүн Ideиңизде ар кандай ыкмаларды сынап көрүүнүStackTrace сунуштайм . Баарын толук өздөштүрө элек болсоңуз да, үйрөнүүнү улантыңыз жана табышмак бул маселеде мен үчүн кандай болсо, ошондой болуп калат. Баарыңарга ийгorк каалайм! Ps Бул материал сизге жакса лайк басып колдоп коюңуз. Сизге кыйын эмес, мен ыраазымын. Рахмат жана 41-деңгээлде көрүшкөнчө;)
Комментарийлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION