Java Class Yapısında Finalize Metotunun Kullanımı
Java'da finalize() Metodu:
Java dili kullanılmayan nesneleri silmek için arka planda çalışan bir sisteme sahiptir. Bu yüzden C++ gibi dillerde dinamik nesne tanımlarında mutlaka yer alması gereken nesneyi silme metodları javada o kadar gerekli değildir. Fakat eğer kendiniz metlaka bir nesneyi acil olarak silmek isteseniz finalize() isimli bir metodu sınıfınızda tanımlayıp kullanabilirsiniz. Örnek olarak aşağıdaki metodu verebiliriz.
Örnek Kullanım:
protected void
finalize() throws Throwable {
try {
close();
}
catch(Exception e) {
}
finally {
super.finalize();
//Buraya uygulamanızla ilgili kodlar yazmanız gerekli...
}
}
Java, C gibi nesneler için sonlandrma yöntemleri vardır bunu C++ keşfetti.Ancak, aynı şekilde Java çöp toplama nedeniyle böyle davranmaz. Java, bir sonlandrma yöntemi aşağıdaki prototip vardır:
protected void finalize();
java.lang.Object. Bu yöntem, bu açık kaynak bir nesne ait yayın istiyor herhangi bir görev yapabilir.
Örnek Olarak:
class Test {
protected void finalize() {
System.out.println("Removed");
}
public static void main(String[] args) {
Test c = new Test();
}
}
Eğer bu program çalıştırıldığında ekrana herhangi bir çıktı gelmezse, aşağıdakini deneyin kesinlikle bir çıktı alacaksınız.
class Test {
protected void finalize() {
System.out.println("Removed");
}
public static void main(String[] args) {
Test c = new Test();
}
}
Her sınıf Nesne ve sınıf yönteminden genellikle çöp toplayıcısı tarafından finalize() fonksiyonu sonlandırmak o nesne var artık referanslar. Nesnenin sınıf yöntemi sonlandrdktan çok normal bir Java sınıf tarafından temizlemek üzerine ise önemli bir hareket yapar sağlar devralır kodu bir dosya yakın örneğin, vb veritabanı bağlantıları kapanış.
Ama en iyi uygulama bir deneyin yakalamak nihayet beyanı ve finalize() yöntemi super.finalize aramak için kullanmaktır.Finalize bir kez ve sadece bir kez, her nesne için çalışır.
Eğer yeni oluşturduğunuz class ınızda composition yöntemi ile diğer class ları kullanmışsanız , bu kullanılan class ların finalize() methodlarının çağrılmasını hakkında herhangi bir endişemiz olamaz .Fakat işin içine kalıtım girerse işler biraz renk değiştirir, şöyleki ; eğer türemiş bir class ın finalize() methodunun içinden ana class ının finalize() methodunu çağırmadınız sürece , ana class ın finalize() methodu çağrılmaz . Bunun sebebi , ilk olarak türetilmiş class ın yok olması gerektiğindendir . Ana class , türemiş class dan daha önce hafısazan silinirse , birçok hata ile karşılaşmamız mümkün.
Aşağıdaki örnekte türemiş class ın finalize() methodunun içinde ana class ın finalize methodu çağılmadı ve bakin ortaya nasil ilginç bir görüntüler çıktı.
Örnekler:
// kalitim ve finalize - I
class Vitamin {
private String isim;
public Vitamin(String gelen) {
isim = gelen;
System.out.println("Vitamin yapilandirici " + isim);
}
public void finalize() {
System.out.println("Vitamin finalize() " + isim);
}
}
class Bugday {
Vitamin a = new Vitamin("Bugday");
public Bugday() {
System.out.println("Bugday yapilandirici");
}
protected void finalize() throws Throwable {
System.out.println("Bugday finalize()");
}
}
class Un extends Bugday {
Vitamin a = new Vitamin("Un");
public Un() {
System.out.println("Un yapilandirici");
}
protected void finalize() throws Throwable {
System.out.println("Un finalize()");
}
}
class Ekmek extends Un {
Vitamin a = new Vitamin("Ekmek");
public Ekmek() {
System.out.println("Ekmek yapilandirici");
}
protected void finalize() throws Throwable {
System.out.println("Ekmek finalize()");
}
}
public class NewJApplet {
public static void main(String args[]) {
new Ekmek();
System.out.println("Temizlik Basliyor .. ");
System.gc();
}
}//^
Çıktı Önizleme:
Constructor (yapilandirici) methodlar daha evvelden değindiğimiz gibi sırasıyla çağrılıyor bu kısımları geçiyorum , dikkatinizi “Temizlik Baslıyordan” sonraya çekmek istiyorum.
Temizlik Basliyor .. Ekmek finalize() Vitamin finalize() Bugday Vitamin finalize() Un Vitamin finalize() Ekmek |
System.gc() komutu ile Garbage Collector tetiklendi , eğer bu komut çağrılmasaydı belkide hiç bir obje hafızandan temizlenmiyecekti (sadece tahmin) çünki Garbage Collector , hafızanın doluluk oranına göre çağrılır . Eğer bizim yazdığımız kod çok fazla çöp obje üretmiyorsa(hafızayı şişirmiyorsak) o zaman GC devreye hicbir zaman girmeyebilir ve tabii o zaman da finalize metoduda çağrılmaz.
Ekmek objesinin finalize() methodu ve kullanığımız üç adet vitamin objesinin finalize() methodları çağrıldı . Bu üç adet vitamin objesinin finalize() methodlarının çağrılmasının sebebi daha evvelden belirttiğim gibi composition yöntemi ile class lara dahil edilmeleri . Peki neden Bugday ve Un objelerinin finalize() methodları çağrılmadı?? Bunun sebebi , Ekmek class ının finalize() metodunda bizim manuel olarak bu class ların finalize() metodlarını çağırmamızdan kaynaklanıyor . Java bu olayda kontrolu bize vermişdir . Kural şöyle : Eğer türemiş class ın varsa , türetilen class ın finalize() methodunu çağırmak senin sorumluluğundadır.
Bir objenin finalize() methodunun çağrılması onun hafızadan atılması anlamına geldiğini daha evvelki konulardan biliyorduk .
Yani ?? , türetilen class ın finalize() methodunun çağrıldığı şekilde yukarıdaki örneği değiştirelim . Objelerin hafızadan silenmesi sıralamasına bakaranız , yaratılma sırasının tam tersi olduğunu göreceksiniz .
Dediklerimizi Kod a dökersek :
// kalitim ve finalize - II
class Vitamin {
private String isim;
public Vitamin(String gelen) {
isim = gelen;
System.out.println("Vitamin yapilandirici " + isim);
}
public void finalize() {
System.out.println("Vitamin finalize() " + isim);
}
}
class Bugday {
Vitamin a = new Vitamin("Bugday");
public Bugday() {
System.out.println("Bugday yapilandirici");
}
protected void finalize() throws Throwable {
System.out.println("Bugday finalize()");
}
}
class Un extends Bugday {
Vitamin a = new Vitamin("Un");
public Un() {
System.out.println("Un yapilandirici");
}
protected void finalize() throws Throwable {
System.out.println("Un finalize()");
super.finalize();
}
}
class Ekmek extends Un {
Vitamin a = new Vitamin("Ekmek");
public Ekmek() {
System.out.println("Ekmek yapilandirici");
}
protected void finalize() throws Throwable {
System.out.println("Ekmek finalize()");
super.finalize();
}
}
public class NewJApplet3 {
public static void main(String args[]) {
new Ekmek();
System.out.println("Temizlik Basliyor .. ");
System.gc();
}
} //^
Ekmek ve Un class larının finalize() metodlarına dikkat edelim . Artik super.finalize() sayesinde türetilen objeninde finalize() methodu da çağrılıyor.Yangın en aşağıdan başlayarak başayalarak en yukarıdaki class doğru ilerleyebilir .
Çıktı Önizleme:
finalize() Metodunun çalışma prensibine örnek olarak:
Mehmet EMEK
Kaynaklar:
- www.programlama.com
- http://www.janeg.ca/scjp/gc/finalize.html
- http://www.java-tips.org/java-ee-tips/enterprise-java-beans/how-to-write-finalization-code-in.html
- http://www.devx.com/Java/Article/30192
- http://forums.sun.com/thread.jspa?threadID=753023
- http://www.programlama.com/sys/c2html/view.php?DocID=36