1. Yığın izi alma

Yığın izi alma

Java programlama dili, bir programcıya bir programda neler olup bittiği hakkında bilgi alması için birçok yol sunar. Ve sadece kelimeler değil.

Örneğin, C++ programları derlendikten sonra, makine koduyla dolu büyük bir dosya haline gelirler ve çalışma zamanında bir programcının kullanabileceği tek şey, yürütülmekte olan makine kodunu içeren bellek bloğunun adresidir. Çok değil diyelim.

Ancak Java için, bir program derlendikten sonra bile sınıflar sınıf olarak kalır, yöntemler ve değişkenler kaybolmaz ve programcının programda neler olduğu hakkında bilgi almak için birçok yolu vardır.

Yığın izleme

Örneğin, bir programın yürütüldüğü noktada, yürütülmekte olan yöntemin sınıfını ve adını öğrenebilirsiniz. Ve tek bir yöntem değil — geçerli yöntemden yönteme kadar tüm yöntem çağrıları zinciri hakkında bilgi alabilirsiniz main().

Geçerli yöntemden, onu çağıran yöntemden ve onu çağıran yöntemden vb. oluşan bir listeye yığın izleme denir . Bu ifade ile alabilirsiniz:

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

Ayrıca iki satır olarak da yazabilirsiniz:

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

currentThread()Sınıfın statik yöntemi , geçerli iş parçacığı, yani geçerli yürütme iş parçacığı hakkında bilgi içeren Threadbir nesneye referans döndürür . Java CoreThread görevinin 17. ve 18. Düzeylerinde diziler hakkında daha fazla bilgi edineceksiniz .

Bu Threadnesne , her biri bir yöntem hakkında bilgi içeren getStackTrace()bir dizi nesne döndüren bir yönteme sahiptir. StackTraceElementBirlikte ele alındığında, tüm bu öğeler bir yığın izi oluşturur .

Örnek:

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

Örneğin konsol çıktısında da görebileceğimiz gibi, getStackTrace()yöntem üç öğeden oluşan bir dizi döndürdü:

  • getStackTrace()Threadsınıfın yöntemi
  • test()Mainsınıfın yöntemi
  • main()Mainsınıfın yöntemi

Bu yığın izlemeden şu sonuca varabiliriz:

  • Yöntem , Main.java dosyasının 11. satırındaki yöntem Thread.getStackTrace()tarafından çağrıldı.Main.test()
  • Yöntem , Main.java dosyasının 5. satırındaki yöntem Main.test()tarafından çağrıldı.Main.main()
  • Yöntemi kimse çağırmadı Main.main()— bu, çağrılar zincirindeki ilk yöntemdir.

Bu arada, ekranda mevcut bilgilerin yalnızca bir kısmı görüntülendi. StackTraceElementDiğer her şey doğrudan nesneden elde edilebilir



2.StackTraceElement

Adından da anlaşılacağı gibi, sınıf, bir yığınStackTraceElement izleme öğesi, yani .stack trace

Bu sınıf aşağıdaki örnek yöntemlerine sahiptir:

Yöntem Tanım
String getClassName()
Sınıfın adını döndürür
String getMethodName()
Yöntemin adını döndürür
String getFileName()
Dosyanın adını döndürür (bir dosya birden çok sınıf içerebilir)
int getLineNumber()
Yöntemin çağrıldığı dosyadaki satır numarasını döndürür
String getModuleName()
Modülün adını döndürür (bu olabilir null)
String getModuleVersion()
Modülün sürümünü döndürür (bu olabilir null)

Geçerli çağrı yığını hakkında daha eksiksiz bilgi almanıza yardımcı olabilirler:

kod Konsol çıkışı Not
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
sınıf adı
yöntem adı
dosya adı satır
numarası modül adı modül sürümü sınıf adı yöntem adı dosya adı satır numarası modül adı modül sürümü sınıf adı yöntem adı dosya adı satır numarası modül adı modül sürümü

















3. Yığın

Yığın izlemenin ne olduğunu zaten biliyorsunuz , ancak yığın (Yığın sınıfı) nedir ?

Yığın, öğeler ekleyebileceğiniz ve öğeleri alabileceğiniz bir veri yapısıdır. Bunu yaparken, yalnızca sondan öğeler alabilirsiniz: önce son ekleneni alırsınız, sonra sondan ikinci ekleneni alırsınız, vb.

Ad yığınının kendisi, bir kağıt yığınıyla nasıl etkileşim kuracağınız gibi, bu davranışı önerir. Sayfa 1, 2 ve 3'ü bir yığına koyarsanız, bunları ters sırada almanız gerekir: önce üçüncü sayfa, sonra ikinci ve ancak ondan sonra birinci.

Java'nın aynı ada ve davranışa sahip özel bir Stack toplama sınıfı bile vardır. ArrayListBu sınıf, ve ile birçok davranışı paylaşır LinkedList. Ancak yığın davranışını uygulayan yöntemleri de vardır:

Yöntemler Tanım
T push(T obj)
objÖğeyi yığının en üstüne ekler
T pop()
Elemanı yığının tepesinden alır (yığın derinliği azalır)
T peek()
Yığının en üstündeki öğeyi döndürür (yığın değişmez)
boolean empty()
Koleksiyonun boş olup olmadığını kontrol eder
int search(Object obj)
Koleksiyondaki bir nesneyi arar ve onun değerini döndürür.index

Örnek:

kod Yığın içeriği (yığının üst kısmı sağdadır)
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]

Yığınlar programlamada oldukça sık kullanılır. Yani bu faydalı bir koleksiyon.



4. İstisna işleme sırasında yığın izi görüntüleme

Yöntem çağrılarının listesine neden yığın izleme adı verilir ? Çünkü metot listesini metot isimleri olan bir kağıt yığını olarak düşünürseniz, bir sonraki metodu çağırdığınızda yığına o metodun ismini taşıyan bir sayfa eklersiniz. Ve bir sonraki kağıt sayfası bunun üzerine gelir ve bu böyle devam eder.

Bir yöntem sona erdiğinde, yığının en üstündeki sayfa kaldırılır. Üzerindeki tüm sayfaları çıkarmadan yığının ortasından bir sayfayı kaldıramazsınız. Benzer şekilde, çağrı zincirinin ortasında bir yöntemi, çağırdığı tüm yöntemleri sonlandırmadan sonlandıramazsınız.

İstisnalar

Yığınların bir başka ilginç kullanımı da istisna işleme sırasındadır.

Bir programda bir hata oluştuğunda ve bir istisna atıldığında , istisna geçerli yığın izlemeyi içerir — ana yöntemden başlayıp hatanın oluştuğu yöntemle biten yöntemlerin bir listesinden oluşan bir dizi. İstisnanın atıldığı satır bile var!

Bu yığın izi, istisna içinde saklanır ve aşağıdaki yöntem kullanılarak istisnadan kolayca alınabilir:StackTraceElement[] getStackTrace()

Örnek:

kod Not
try
{
   // An exception may occur here
}
catch(Exception e)
{
   StackTraceElement[] methods = e.getStackTrace()
}




İstisnayı yakalayın

Hata oluştuğunda var olan yığın izlemeyi alın.

Bu, sınıfın bir yöntemidir Throwable, bu nedenle tüm alt öğeleri (yani, tüm istisnalar) bu getStackTrace()yönteme sahiptir. Süper uygun, ha?

İstisnanın yığın izlemesini göster

Bu arada, Throwablesınıfın, istisna içinde depolanan tüm yığın izleme bilgilerini görüntüleyen bir yöntem olan yığın izlemeleriyle çalışmak için başka bir yöntemi vardır. denir printStackTrace().

Oldukça uygun bir şekilde, herhangi bir istisnada arayabilirsiniz.

Örnek:

kod
try
{
   // An exception may occur here
}
catch(Exception e)
{
   e.printStackTrace();
}
Konsol çıkışı
java.base/java.lang.Thread.getStackTrace(Thread.java:1606)
Main.test(Main.java:11)
Main.main(Main.java:5)