JAVA Bytecode Ayrıntılı İnceleme
başlıklı önceki yazımda, hazırlamış olduğum ByteCodeTest isimli sınıfınJAVA bytecode'unu nasıl elde edeceğimizi açıklamıştım. Bu yazımda ise, yazmış olduğum JAVA kodlarını ve karşılık gelen JAVA bytecode'larını inceleyeceğim.
Bu amaçla ilk önce ByteCodeTest.java sınıfını aynen kullanarak karşılaştırma yapacağım, daha sonra ise bu sınıfa bir method daha ekleyip string ekleme / birleştirme (string concatenation) işlemini JAVA bytecode'ları yardımıyla inceleyeceğim ve basit ama önemli bir konudan bahsedeceğim... (Devam)
ÖNEMLİ NOT : Bloglarda yazılan yazıları kopyalayıp kendi sitenizde, forumlarda yayınlamak çok hoş gibi görünse de aslında makaleyi yazan kişinin cesaretini kıran, motivasyonunu yok eden bir davranıştır. Burada yazılan yazıların da bir kısmını ya da tamamını kaynak göstermeden kopyalayan kişidüdüklü tenceredir, Sarkozy'dir.
Şimdi, sınıfımızın constructor'ı olan:
Kod:
public ByteCodeTest() {
i = 0;
}
kodlara karşılı gelen JAVA bytecode'u şu şekilde idi:
Kod:
public deneme.ByteCodeTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>")V
4: aload_0
5: iconst_0
6: putfield #2 // Field i:I
9: return
Burada ilginç olan, 1: no'lu satırda invokespecial kodu ile Object sınıfının constructor'ının çağırılıyor olması. Sebebi ise, tabi ki her bir JAVA sınıfının Object sınıfından kalıtım yoluyla elde ediliyor olmasıdır.
Geçelim artir() methoduna. Methodumuz şöyle idi:
Kod:
public void artir() {
i = i + 1;
}
Yaptığı iş i global değişkeninin değerini 1 artırmak olan bu methodun JAVA bytecode'u ise:
Kod:
public void artir();
Code:
0: aload_0
1: aload_0
2: getfield #2 // Field i:I
5: iconst_1
6: iadd
7: putfield #2 // Field i:I
10: return
şeklinde oluyordu. Şimdi burada 1: no'lu satıra sonra incelemek üzere vurgu yaparak diğer komutlara bakalım.
2: getfield #2 ile i global değişkeni stack'e alınıyor.
5: iconst_1 ile değeri bir olan bir int oluşturulup stack'e alınıyor.
6: iadd stack'teki bu iki değişken, integer toplama ile toplanıyor.
7: putfield #2 ile toplanan bu değer i global değişkenine atanıyor.
Şimdi de artirAlternatif() methoduna bakıyorum.
Kod:
public void artirAlternatif() {
i++;
}
Bu methodun işlevi yukarıdaki artir() methodu ile tamamen aynı. Ancak JAVA bytecode'una baktığımızda bir fark göreceğiz:
Kod:
public void artirAlternatif();
Code:
0: aload_0
1: dup
2: getfield #2 // Field i:I
5: iconst_1
6: iadd
7: putfield #2 // Field i:I
10: return
artir() methodunda 1: no'lu satırda
Kod:
1: aload_0
komutu varken, artirAlternatif() methodunda 1: no'lu satırda
Kod:
1: dup
komutunu görüyoruz. dup komutu duplicate (aynısını yapmak, çoğaltmak) kelimesinin kısaltılmasından oluşmuş olup stack'teki değerin bir kopyasının daha stack'e eklenmesini sağlamaktadır. Bunun haricinde geriye kalan kodların birebir aynı olduğunu görüyoruz.
NOT : İşlevi aynı olan ancak global olan i değişkeni yerine lokal bir integer değişken üzerinde aynı işlemleri yapan yeni methodlar yazdığımızda ise tamamen farklı olan iinc 1,1 gibi bir komutla karşılaşacağız. Bunu da burada anlatmayalım, siz deneyin.
String'ler ile yaptığımız ekleme / birleştirme / concatenation işlemlerini JAVA bytecode bakış açısından bir sonraki yazımda inceleyeceğim. Buradaki basit örnekleri karmaşıklaştırmak, zorlaştırmak istemedim.
Linkleri sadece kayıtlı üyeler görebilir. Linkleri görebilmek için Üye Girişi yapın veya ücretsiz olarak Kayıt Olun
Bu amaçla ilk önce ByteCodeTest.java sınıfını aynen kullanarak karşılaştırma yapacağım, daha sonra ise bu sınıfa bir method daha ekleyip string ekleme / birleştirme (string concatenation) işlemini JAVA bytecode'ları yardımıyla inceleyeceğim ve basit ama önemli bir konudan bahsedeceğim... (Devam)
ÖNEMLİ NOT : Bloglarda yazılan yazıları kopyalayıp kendi sitenizde, forumlarda yayınlamak çok hoş gibi görünse de aslında makaleyi yazan kişinin cesaretini kıran, motivasyonunu yok eden bir davranıştır. Burada yazılan yazıların da bir kısmını ya da tamamını kaynak göstermeden kopyalayan kişidüdüklü tenceredir, Sarkozy'dir.
Şimdi, sınıfımızın constructor'ı olan:
Kod:
public ByteCodeTest() {
i = 0;
}
kodlara karşılı gelen JAVA bytecode'u şu şekilde idi:
Kod:
public deneme.ByteCodeTest();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>")V
4: aload_0
5: iconst_0
6: putfield #2 // Field i:I
9: return
Burada ilginç olan, 1: no'lu satırda invokespecial kodu ile Object sınıfının constructor'ının çağırılıyor olması. Sebebi ise, tabi ki her bir JAVA sınıfının Object sınıfından kalıtım yoluyla elde ediliyor olmasıdır.
Geçelim artir() methoduna. Methodumuz şöyle idi:
Kod:
public void artir() {
i = i + 1;
}
Yaptığı iş i global değişkeninin değerini 1 artırmak olan bu methodun JAVA bytecode'u ise:
Kod:
public void artir();
Code:
0: aload_0
1: aload_0
2: getfield #2 // Field i:I
5: iconst_1
6: iadd
7: putfield #2 // Field i:I
10: return
şeklinde oluyordu. Şimdi burada 1: no'lu satıra sonra incelemek üzere vurgu yaparak diğer komutlara bakalım.
2: getfield #2 ile i global değişkeni stack'e alınıyor.
5: iconst_1 ile değeri bir olan bir int oluşturulup stack'e alınıyor.
6: iadd stack'teki bu iki değişken, integer toplama ile toplanıyor.
7: putfield #2 ile toplanan bu değer i global değişkenine atanıyor.
Şimdi de artirAlternatif() methoduna bakıyorum.
Kod:
public void artirAlternatif() {
i++;
}
Bu methodun işlevi yukarıdaki artir() methodu ile tamamen aynı. Ancak JAVA bytecode'una baktığımızda bir fark göreceğiz:
Kod:
public void artirAlternatif();
Code:
0: aload_0
1: dup
2: getfield #2 // Field i:I
5: iconst_1
6: iadd
7: putfield #2 // Field i:I
10: return
artir() methodunda 1: no'lu satırda
Kod:
1: aload_0
komutu varken, artirAlternatif() methodunda 1: no'lu satırda
Kod:
1: dup
komutunu görüyoruz. dup komutu duplicate (aynısını yapmak, çoğaltmak) kelimesinin kısaltılmasından oluşmuş olup stack'teki değerin bir kopyasının daha stack'e eklenmesini sağlamaktadır. Bunun haricinde geriye kalan kodların birebir aynı olduğunu görüyoruz.
NOT : İşlevi aynı olan ancak global olan i değişkeni yerine lokal bir integer değişken üzerinde aynı işlemleri yapan yeni methodlar yazdığımızda ise tamamen farklı olan iinc 1,1 gibi bir komutla karşılaşacağız. Bunu da burada anlatmayalım, siz deneyin.
String'ler ile yaptığımız ekleme / birleştirme / concatenation işlemlerini JAVA bytecode bakış açısından bir sonraki yazımda inceleyeceğim. Buradaki basit örnekleri karmaşıklaştırmak, zorlaştırmak istemedim.