Bu yazımda Java programclarının bilmediği, doğru olarak kabul edip kullandığı ya da yanlış bildiği konulardan bahsetmek istiyorum.
Hafıza Alanı Ayarları
Genelde JVM için hazıfa alanı -Xmx -Xms parametreleri ile oluşturulur. -X ile başlayan parametreler standart JVM parametreleri değildirler, yani bu parametreleri JVM implemente etmek zorunda değildir. Durum böyle olunca -Xmx1024m şeklindeki bir parametre, eğer JVM -Xmx parametresini implemente etmedi ise JVM için kullanılan hafıza alanının 1GB olarak ayarlanmasını sağlayamayacaktır. -Xmx ve -Xms yerine standart olan -mx ve -ms parametreleri kullanılmalıdır.
finally Bloğu
try/catch/finally yapısında metot son bulmadan önce finally bloğunda yer alan kodun mutlaka koşturulduğu düşünülür. Ama bu tam doğru değildir. İki durumda finally içinde yer alan kod koşturulmaz. Bu iki durum: Eğer try içinde System.exit(0); komutu kullanıldı ise (bu durumda program hemen son bulur) ya da bir Thread try içindeki kodları koştururken bilgisayarın elektriği kesilirse ;-)
Call By Reference
Java tamamen call by value mantığı ile çalışır. Java’da call by reference mantığı olduğu bir yanılgıdır. Primitif veri tipleri (int, long vs) nasıl metotlara parametre olarak gönderildiklerinde değerleri kopyalanıyorsa, nesne referansları da metot için oluşturulan stack’e kopyalanır. Referans bir göstergeştir (pointer). Bir metoda parametre olarak gönderildiğinde, çoğaltılarak aynı nesneye işaret eden ikinci bir göstergeç oluşturulur. İkinci göstergeç te aynı nesneye işaret ettiği için, metot içinde işaret ettiği nesne üzerinde işlem yaparak nesnenin durumunu değiştirebilir. Bu değişikliklere metot dışındaki göstergeç üzerinden de erişmek mümkündür, çünkü iki göstergeç aynı nesneye işaret etmektedir. Metot içinde oluşturulan ikinci göstergece null değeri atandığında, metot dışındaki göstergeç bu durumdan etkilenmez. Bu nesne referanslarının metotlara parametre olarak gönderildiklerinde kopyalandıkları yani call by value mantığı ile çalıştıkları anlamına gelmektedir.
Java’da sadece call by value mantığının kullanıldığının kanıtı Java spesifikasyonunda yer alan şu cümledir :
When the method or constructor is invoked (15.12), the values of the actual argument expressions initialize newly created parameter variables, each of the declared Type, before execution of the body of the method or constructor. The Identifier that appears in the DeclaratorId may be used as a simple name in the body of the method or constructor to refer to the formal parameter.
String ve StringBuilder
“a”+”b” ile StringBuilder.append(“a”).append(“b”) arasında bytecode seviyesinde bir farklılık yoktur. “a”+”b” kullanıldığı taktirde bu bytecode seviyesinde StringBuilder.append(“a”).append(“b”) şekline dönüştürülür.
public class Test { public static void main(String[] args) { StringBuilder temp = new StringBuilder(); temp.append("a"); temp.append("b"); String a ="a"; String b = "b"; System.out.println(a+b); } }
C:\Temp>javap -c Test Compiled from "Test.java" public class Test extends java.lang.Object{ public Test(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: new #2; //class java/lang/StringBuilder 3: dup 4: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V 7: astore_1 8: aload_1 9: ldc #4; //String a 11: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 14: pop 15: aload_1 16: ldc #6; //String b 18: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 21: pop 22: ldc #4; //String a 24: astore_2 25: ldc #6; //String b 27: astore_3 28: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream; 31: new #2; //class java/lang/StringBuilder 34: dup 35: invokespecial #3; //Method java/lang/StringBuilder."<init>":()V 38: aload_2 39: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 42: aload_3 43: invokevirtual #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 46: invokevirtual #8; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 49: invokevirtual #9; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 52: return }
Bu yazım devam edecek!!! Sizde bildiklerinizi lütfen yorum olarak bu yazıya ekleyin.
Özcan Bey merhabalar,
Call By Reference ile ilgili söylediğiniz durumu C# ta denedim. Aynı durum C# için de geçerli. Her gün yeni birşeyler öğrenmemize vesile olduğunuz için teşekkür ederim.
Selamlar
Geri izleme: Java’da Bilinmeyenler | Mert Bozkurt
Hocam merhaba ben denedim fakat yazı yaz konsolda çıkıyor. Yani finally bloğu çalışıyor acaba ben mi yanlış anladım böyle değil mi?
try{
System.out.println(1/0);
System.exit(0);
}
finally{
System.out.println(“yazı yaz”);
}
Biraz önce Java 7 sürümü ile denedim, System.exit() sonrasindaki final blogunda gelen yazi ekranda görünmedi. JVM sürümü ile iliskili olabilir, ama normal sartlar altinda System.exit() ile JVM terminate edililir ve sonrasindaki hicbir kod kosturulmaz.
Hocam bende eclipse ve jdk 1.7 var. Ekran çıktısı ise şöyle; http://i.hizliresim.com/onm0mQ.png
Sizde biri sifira böldügünüz icin AritmeticException olusmus ve System.exit() kosturulmadan kod finally bloguna düsmüs, o yüzden “yazi yaz” ciktisini aliyorsunuz.
Hocam kusura bakmayın uzatıyorum ama acaba bir örnek kod verebilir misiniz finally bloğu çalışmayan?
try icinde sadece System.out.println ile bir cikti al, daha sonra System.exit() ile programi sonlandir. finally blogunda yine bir System.out ciktisi olsun. System.exit() den sonra finally blogunda yer alan cikti ekranda görünmez. Sizin örneginizde bir Exception olustugu icin dogrudan catch blogunda atlanmak istemis, o olmadigi icin, finally blogundaki cikti alinmis, yani Exception dan ötürü System.exit kosturulamamis. Siz örneginizdeki bölme islemini kaldirin ya da 1/1 seklinde degistirin, finally blogundaki ciktinin ekranda görüntülenmedigini göreceksiniz. System.exit ile program son bulur.