CodeGym /Kurslar /Java SELF AZ /Stack trace

Stack trace

Java SELF AZ
Səviyyə , Dərs
Mövcuddur

1. Stack trace əldə etmək

Stack trace əldə etmək

Java proqramlaşdırma dilində proqramçıda proqramda hazırda nə baş verdiyini öyrənmək üçün çoxlu üsulları var. Və bu sadəcə söz deyil.

Məsələn, C++ proqramlaşdırma dilindəki proqramlar kompilyasiya olunduqdan sonra böyük bir maşın kodu faylına çevrilir və iş vaxtı mövcud olan tək şey indi icra olunan maşın kodunun saxlandığı yaddaş ünvanıdır. Açığı, bu çox deyil.

Amma Java-da kompilyasiyadan sonra belə siniflər siniflər olaraq qalır, metodlar və dəyişənlər itmir, beləliklə proqramçıda proqramda indi baş verənlər haqqında məlumat əldə etmək üçün çoxlu üsulları var.

Stack trace

Məsələn, proqramın istənilən anında hazırda icra olunan metodu və sinifi öyrənmək mümkündür. Hətta bir metod yox, main() metoduna qədər metodların çağırma zənciri haqqında məlumat əldə etmək mümkündür.

Müasir metod, onu çağıran metod, onu çağıran metod və s. ibarət siyahıya stack trace deyilir. Onu almaq üçün bu komandanı istifadə edə bilərik:

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

Onu iki sətir olaraq da yazmaq olar:

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

Thread sinifinin currentThread() statik metodu cari thread haqqında məlumat saxlayan Thread obyektinə istinad qaytarır. Thread-lər haqqında daha çox Java Core kursunda öyrənəcəksiniz.

Bu Thread obyektində getStackTrace() metodu var, hansı ki, hər biri bir metod haqqında məlumat saxlayan StackTraceElement elementlərindən ibarət array qaytarır. Bütün elementlər bir yerdə stack trace yaradır.

Nümunə:

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);
   }
}
Ekrana çıxış
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)

Ekrana çıxışdan gördüyümüz kimi, bu nümunədə getStackTrace() metodu üç elementdən ibarət array qaytarıb:

  • Thread sinifinin getStackTrace() metodu
  • Main sinifinin test() metodu
  • Main sinifinin main() metodu

Bu stack trace-dən belə nəticə çıxarmaq olar ki:

  • Thread.getStackTrace() metodu Main.test() metodu tərəfindən Main.java faylının 11-ci sətrində çağırılıb
  • Main.test() metodu Main.main() metodu tərəfindən Main.java faylının 5-ci sətrində çağırılıb
  • Main.main() heç kim tərəfindən çağırılmayıb — bu çağırma zəncirindəki ilk metoddur.

Bu arada, ekranda yalnız mövcud məlumatın bir hissəsi göstərilib. Qalan hər şeyi birbaşa StackTraceElement obyektindən əldə etmək olar



2. StackTraceElement

StackTraceElement sinfi, adına uyğun olaraq, bir stack trace elementinə - yəni StackTrace-dən bir metoda aid məlumatları saxlamaq üçün yaradılıb.

Bu sinfin obyektləri üçün aşağıdakı metodlar mövcuddur:

Metod Təsvir
String getClassName()
Sinfin adını qaytarır
String getMethodName()
Metodun adını qaytarır
String getFileName()
Faylın adını qaytarır (bir faylda bir neçə sinif ola bilər)
int getLineNumber()
Metodun çağırıldığı sətrin nömrəsini qaytarır
String getModuleName()
Modulun adını qaytarır (null ola bilər)
String getModuleVersion()
Modulun versiyasını qaytarır (null ola bilər)

Bu metodlarla cari çağırış stack-i haqqında daha ətraflı məlumat ala bilərsiniz:

Kod Ekrana çıxış Qeyd
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
sinfin adı
metodun adı
faylın adı
sətrin nömrəsi
modulun adı
modulun versiyası

sinfin adı
metodun adı
faylın adı
sətrin nömrəsi
modulun adı
modulun versiyası

sinfin adı
metodun adı
faylın adı
sətrin nömrəsi
modulun adı
modulun versiyası


3. Stack

Stack Trace-in nə olduğunu artıq bilirsiz, bəs Stack (Stack) özünün nə olduğunu bilirsizmi?

Stack — bu, məlumatları saxlamaq üçün bir strukturdur. Buraya elementlər əlavə etmək və elementləri götürmək mümkündür. Amma elementləri yalnız sondan götürmək olar: əvvəl sonuncu əlavə edilən, sonra — ondan əvvəlki və s.

"Stack" adı ingilisdən tərcümədə "çalxalanma" deməkdir və kağız vərəqlərinin çalxası ilə çox oxşardır. Əgər siz kağız çalxasına 1, 2 və 3 nömrəli vərəqlər qoysanız, onları yalnız tərs qaydada götürə bilərsiniz: əvvəlcə üçüncü, sonra ikinci və yalnız sonra birinci vərəqi.

Java-da hətta bu cür davranışı olan və həmin addakı xüsusi bir kolleksiya da var — Stack. Bu sinif davranış baxımından ArrayListLinkedList-ə çox oxşayır. Amma onun Stack davranışını həyata keçirən üsulları da var:

Metodlar Təsvir
T push(T obj)
Elementi obj siyahının sonuna əlavə edir (çalxanın üstü)
T pop()
Çalxanın üstündən elementi götürür (çalxanın hündürlüyü azalır)
T peek()
Çalxanın üstündəki elementi qaytarır (çalxa dəyişmir)
boolean empty()
Kolleksiyanın boş olub-olmadığını yoxlayır
int search(Object obj)
Kolleksiyadan obyekt axtarır, onun index-ini qaytarır

Nümunə:

Kod Stack məzmunu (sağda üst)
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 proqramlaşdırmada tez-tez istifadə olunur. Ona görə də, bu çox faydalı bir kolleksiyadır.



4. Xətaların emalında stack trace çıxışı

Metod çağırışlarının siyahısını niyə StackTrace adlandırıblar? Çünki metodların siyahısını metod adları olan vərəqlərdən ibarət bir yığın kimi təsəvvür etsək, hər yeni metod çağırıldığında həmin metodun adı ilə bir vərəq bu yığına əlavə olunur, onun üstünə - növbəti və s.

Metod tamamlandıqda, yığının üstündəki vərəq götürülür. Yığının ortasından bir vərəqi, onun üstündəki bütün vərəqləri götürmədən çıxarmaq mümkün deyil - metodları zəncirvarı çağırışlarda onun çağırdığı bütün metodlar tamamlanmadan dayandırmaq mümkün deyil.

İstisnalar

Stack-in başqa bir maraqlı istifadəsi - istisnaların emalıdır.

Proqramda səhv baş verəndə və istisna yaradıldığında, hazırkı stack trace ora yazılır: metodlar siyahısından ibarət olan bir massiv, main metodundan başlayaraq səhv baş verən metoda qədər gedir. Hətta istisnanın yaradıldığı sətir orda olur!

Bu xətanın stack trace-i istisnanın içində saxlanılır və ondan asanlıqla aşağıdakı metod vasitəsilə çıxarıla bilər: StackTraceElement[] getStackTrace()

Nümunə:

Kod Qeyd
try
{
   // burda istisna baş verə bilər
}
catch(Exception e)
{
   StackTraceElement[] methods = e.getStackTrace()
}




İstisnanı tuturuq

Xətanın baş verdiyi anda onun stack trace-ni əldə edirik.

Bu Throwable sinfinin metodudur, yəni onun bütün törəmə sinifləri (yəni ümumiyyətlə bütün istisnalar) getStackTrace() metoduna malikdir. Çox rahatdır, elə deyilmi?

Xətanın stack trace çapı

Yeri gəlmişkən, Throwable sinfinin stack trace ilə işləmək üçün daha bir metodu var: o, stack trace-da saxlanılan bütün məlumatları konsola çıxarır. Onun adı printStackTrace()-dır.

Bu metodu istənilən istisnada çağırmaq olar, çox rahatdır.

Nümunə:

Kod
try
{
   // burda istisna baş verə bilər
}
catch(Exception e)
{
   e.printStackTrace();
}
Ekrana çıxış
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)

Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION