Stack trace

All lectures for UZ purposes
Daraja, Dars
Mavjud

1. Stack trace-ni olish

Получение стек-трейса

Java dasturlash tilida dasturchi dasturda nima sodir bo'layotganini bilish uchun juda ko'p usullarga ega. Va bu faqat so'zlar emas.

Masalan, C++ tilidagi dasturlar kompilyatsiyadan so'ng bitta katta mashina kodi fayliga aylanadi va ijro etish vaqtida dasturchiga mavjud bo'lgan barcha narsa - bu mashina kodini o'z ichiga olgan xotira qismining manzili, hozir bajarilayotgan kod. Ha, bu juda ko'p emas.

Java da esa, hatto kompilyatsiyadan keyin ham, klasslar klass bo'lib qoladi, metodlar va o'zgaruvchilar hech qayerga yo'qolmaydi va dasturchi dasturda nima sodir bo'layotganini bilish uchun ko'p yo'llarga ega.

Stack trace

Masalan, dastur ishlayotganda hozirgi bajarilayotgan metod va klassni bilib olish mumkin. Va hatto bitta metod emas, balki main() metodiga qadar bo'lgan barcha metodlar zanjiri haqida ma'lumot olish mumkin.

Hozirgi metoddan tortib, uni chaqirgan metodga, undan keyingi metod va hokazolardan tashkil topgan ro'yxat umumiy holda stack trace deb ataladi. Uni quyidagi buyruq yordamida olish mumkin:

StackTraceElement[] methods = Thread.currentThread().getStackTrace();

Bu kodni ham ikki qatorga yozish mumkin:

Thread current = Thread.currentThread();
StackTraceElement[] methods = current.getStackTrace();

Thread klassining currentThread() statik metodi Thread tipidagi ob'ektni qaytaradi, u hozirgi ip (ijro etish oqimi) haqida ma'lumotni o'z ichiga oladi. Iplar haqida batafsil Java Core kvestida bilib olasiz.

Bu Thread ob'ekti StackTraceElement elementlarining massivini qaytaradigan getStackTrace() metodiga ega, ularning har biri bitta metod haqida ma'lumotni o'z ichiga oladi. Barcha elementlar birgalikda stack trace hosil qiladi.

Misol:

Kod
public class Main
{
   public static void main(String[] args)
   {
      test();
   }

   public static void test()
   {
      Thread current = Thread.currentThread();
      StackTraceElement[] methods = current.getStackTrace();

      for(var info: methods)
         System.out.println(info);
   }
}
Ekranga chiquvchi natija
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)

Natijani ekranda ko'rib turganingizdek, keltirilgan misolda getStackTrace() metodi uchta elementdan iborat massivni qaytardi:

  • getStackTrace() usuli, Thread klassiga tegishli
  • test() usuli, Main klassiga tegishli
  • main() usuli, Main klassiga tegishli

Ushbu stack-trace'dan quyidagilarni aniqlash mumkin:

  • Thread.getStackTrace() metodi Main.test() tomonidan 11-qatorida Main.java faylida chaqirilgan
  • Main.test() metodi Main.main() tomonidan 5-qatorida Main.java faylida chaqirilgan
  • Main.main() metodi hech kim tomonidan chaqirilmagan — bu chaqiruvlar zanjiridagi birinchi usul.

Aytgancha, ekranda faqat mavjud bo'lgan ma'lumotlarning bir qismi ko'rsatildi. Qolgan hamma narsa StackTraceElement ob'ektidan to'g'ridan-to'g'ri olinishi mumkin



2. StackTraceElement

StackTraceElement klassi, o'z nomidan ko'rinib turibdiki, stack trace'ning bitta elementini, ya'ni StackTracedagi bitta metod haqida ma'lumot saqlash uchun yaratilgan.

Ushbu klassdagi ob'ektlar quyidagi metodlarga ega:

Metod Ta'rifi
String getClassName()
Klass nomini qaytaradi
String getMethodName()
Metod nomini qaytaradi
String getFileName()
Fayl nomini qaytaradi (bitta faylda bir nechta klasslar bo'lishi mumkin)
int getLineNumber()
Metod chaqirilgan satrning raqamini qaytaradi
String getModuleName()
Module nomini qaytaradi (bo'lishi mumkin null)
String getModuleVersion()
Module versiyasini qaytaradi (bo'lishi mumkin null)

Ular yordamida hozirgi chastota chaqiruvlar haqida yanada to'liq ma'lumot olishingiz mumkin:

Kod Ekranga chiquvchi natija Izoh
public class Main
{
   public static void main(String[] args)
   {
      test();
   }

   public static void test()
   {
      Thread current = Thread.currentThread();
      StackTraceElement[] methods = current.getStackTrace();

      for(StackTraceElement info: methods)
      {
         System.out.println(info.getClassName());
         System.out.println(info.getMethodName());

         System.out.println(info.getFileName());
         System.out.println(info.getLineNumber());

         System.out.println(info.getModuleName());
         System.out.println(info.getModuleVersion());
         System.out.println();
      }
   }
}
java.lang.Thread
getStackTrace
Thread.java
1606
java.base
11.0.2

Main
test
Main.java
11
null
null

Main
main
Main.java
5
null
null
klass nomi
metod nomi
fayl nomi
satr raqami
module nomi
module versiyasi

klass nomi
metod nomi
fayl nomi
satr raqami
module nomi
module versiyasi

klass nomi
metod nomi
fayl nomi
satr raqami
module nomi
module versiyasi


3. Stack

Stack Trace nima ekanligini bilib oldingiz, endi esa Stack (Stack) o'zi nima?

Stack - bu ma'lumotlarni saqlash tuzilmasi bo'lib, unga elementlarni qo'shish va undan elementlarni olish mumkin. Ammo elementlarni faqat oxiridan olish mumkin: avval qo'shilgan oxirgi elementni, so'ng - oxirgisi, va hokazo.

Stack so'zining o'zi ingliz tilidan "stack" deb tarjima qilinadi va qog'ozlar ustuniga juda o'xshaydi. Agar siz qog'ozlar ustiga 1, 2 va 3 varaq qo'ysangiz, ularni faqat teskari tartibda olishingiz mumkin: avval uchinchi, so'ng ikkinchi, va faqat keyin birinchi.

Java'da hatto shunday xatti-harakatlar bilan maxsus kollektsiya va shunday nom bilan - Stack mavjud. Ushbu klass o'z xatti-harakatlarida ArrayList va LinkedList ga juda o'xshaydi. Ammo unda stack xatti-harakatlarini amalga oshiruvchi ham usullar mavjud:

Usullar Ta'rifi
T push(T obj)
Ro'yxat oxiriga (ustiga) obj elementini qo'shadi
T pop()
Stackdan ustki elementni oladi (stack balandligi kamayadi)
T peek()
Stackdan ustki elementni qaytaradi (stack o'zgarmaydi)
boolean empty()
Kollektsiya bo'sh ekanligini tekshiradi
int search(Object obj)
Kollektsiyadan ob'ektni qidiradi, uning index ni qaytaradi

Misol:

Kod Stack mazmuni (ustki qismi o'ngda)
Stack<Integer> stack = new Stack<Integer>():
stack.push(1);
stack.push(2);
stack.push(3);
int x = stack.pop();
stack.push(4);
int y = stack.peek();
stack.pop();
stack.pop();

[1]
[1, 2]
[1, 2, 3]
[1, 2]
[1, 2, 4]
[1, 2, 4]
[1, 2]
[1]

Stack dasturlashda juda tez-tez ishlatiladi. Shunday ekan, bu foydali kollektsiya.



4. Xatoliklarni boshqarishda stack-trace chiqarish

Nega metodlar chaqirilish ro'yxatini StackTrace deb nomlaganlar? Chunki metodlar ro'yxatini metodlar nomi bo'lgan varaqalar to'plami sifatida tasavvur qilsangiz, navbatdagi metod chaqirilganda, bu varaqalar to'plamiga metod nomi bilan varaq qo'yiladi, keyin unga navbatdagi qo'yiladi va hokazo.

Metod tugaganda, varaq to'plamdan olinadi. To'plam o'rtasidagi varaqani ustidagi barcha varaqalarni olib tashlamasdan olib bo'lmaydi - chaqirilgan metodlar tugamasdan zanjirida metod ishi tugatilmaydi.

Istisnolar

Stackning yana bir qiziqarli qo'llanishi - istisnolarni boshqarish.

Dasturda xatolik yuzaga kelganda va istisno yaratilganda, unga hozirgi stack trace yoziladi: metodlar ro'yxatidan iborat bo'lgan massiv, dastlabki metoddan to xatolik yuz bergan metodgacha boʻlgan roʻyxat. Hatto istisno yaratilgan satr ham bor!

Bu stack trace xatosi istisno ichida saqlanadi va uni undan olib tashlash oson, quyidagi metod yordamida: StackTraceElement[] getStackTrace()

Misol:

Kod Izoh
try
{
   // bu yerda istisno yuzaga kelishi mumkin
}
catch(Exception e)
{
   StackTraceElement[] methods = e.getStackTrace()
}




Istisnoni ushlash

Undan xatolik yuzaga kelgan paytda stack trace-ni olish.

Bu Throwable klassining metodi, ya'ni uning barcha klass-yashovchilari (ya'ni, barcha istisnolar) getStackTrace() metodiga ega. Juda qulay, to'g'rimi?

Xatolik stack-trace ni chop etish

Aytgancha, Throwable klassida stack trace bilan ishlash uchun yana bir metod mavjud: u istisno ichida saqlangan stack trace haqida to'liq ma'lumotni konsolga chiqaradi. Bu printStackTrace() deb ataladi.

Uni har qanday istisno ob'ektida chaqirish mumkin, bu juda qulay.

Misol:

Kod
try
{
   // bu yerda istisno yuzaga kelishi mumkin
}
catch(Exception e)
{
   e.printStackTrace();
}
Ekranga chiquvchi natija
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)

Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION