Ana içeriğe atla

Java Final Kavramı

Final Kavramı

Final kelimesinin sözlük anlamı "son" demektir.Java programlama dilindeki final kavramıda , sözlük anlamıyla paralel şekilde davranır. Java programlama dilinde final anahtar kelimesi değiştirilemezliği simgiler. Değiştirilemezliğin seçilmesi iki sebebten dolayı olabilir , birincisi tasarım ikincisi ise verimlilik ; Global olan değişkenlere (statik ve değil) , metodlara(statik veya değil) veya sınıflara final kavramını uygulayabiliriz.

Global değişkenler ve Final Kavramı

Global değişkenler ile final kavramı birleştiği zaman , ortaya diğer programlama dillerindeki sabit değer özelliği ortaya çıkar.Global olan sabit değişkenler ister statik olsun veya olmasın final özelliğine sahip olabilir. Java programlama dilinde final olan global değişkenlerin değeri derleme anında veya çalışma anında belli olabilir ama dikkat edilmesi gereken husus, final global değişkenlere sadece bir kere değer atanabiliyor olmasıdır.Sonuç olarak global olan final değişkenleri ikiye ayırabiliriz ;
· Derleme anında değerlerini bilebildiğimiz final global değişkenler.
· Çalışma anında değerlerini bilebildiğimiz final global değişkenler.
ör-FinalOrnek
class  Kutu {
        int i  = 0 ;
}
 
public class FinalOrnek {
 
        final int X_SABIT_DEGER = 34 ;
        final static int Y_SABIT_DEGER = 35 ;
 
        final int  A_SABIT_DEGER  = (int)(Math.random()*50);
 
        final Kutu k = new Kutu() ;
 
        public static void main(String args[]) {
               FinalOrnek fo = new FinalOrnek();
               //fo.X_SABIT_DEGER = 15 ! Hata !
               //fo.Y_SABIT_DEGER = 16 ! Hata !
               //fo.A_SABIT_DEGER = 17 ! Hata !
               fo.k.i = 35 ; // dogru
               // fo.k = new Kutu()  ! hata ! 
               System.out.println("X_SABIT_DEGER = "+fo.X_SABIT_DEGER) ;
               System.out.println("Y_SABIT_DEGER = "+fo.Y_SABIT_DEGER) ;
               System.out.println("A_SABIT_DEGER = "+fo.A_SABIT_DEGER) ;
               System.out.println("Kutu.i = "+fo.k.i) ;
 
        } 
}
Yukarıdaki örneğimizi incelersek , X_SABIT_DEGER ve Y_SABIT_DEGER değişkenlerinin değerlerini derleme anında bilebiliriz , ama A_SABIT_DEGER değişkenin değerini derleme anında bilmek zordur (Math sınıfına ait statik bir metod olan random() , 1 ile 50 arasında rasgele sayılar üretir), bu değişkenin değeri çalışma anında belli olacaktır fakat tüm final özelliğine sahip olan değişkenlere sadece ve sadece bir kere değer atanmaktadır.
Bir global değişkene , final ve statik özellikler belirtirseniz , global değişkenimiz , bu sınıfa ait olan tüm objeler için tek olur (bkz) ve değeri sonradan değiştiremez.
Final kavramında , ilkel tipdeki değişkenler ile obje tipindeki değişkenlerin arasında büyük bir fark vardır.Yukarıdaki örneğimizi incelerseniz , X_SABIT_DEGER, Y_SABIT_DEGER , A_SABIT_DEGER değişkenleri hep ilkel tipdeydi , yani değerlerini kendi üzerlerinde taşıyorlardı . Kutu tipinde k değişkenimizi final yaptığımızda olaylar biraz değişir, Kutu tipindeki k değişkenini final yaparak , bu değişkenin başka bir Kutu objesine tekrardan bağlanmasına izin vermeyiz ama Kutu tipindeki k değişkeninin bağlı olduğu objenin içeliği değişebilir.Uygulamamızın çıktısı aşağıdaki gibi olur;
X_SABIT_DEGER = 34
Y_SABIT_DEGER = 35
A_SABIT_DEGER = 39
Kutu.i = 35

Final parametreler

Metodlar'a gönderilen parametre değerlerinin değişmemesini istiyorsak , bu parametreleri final yapabiliriz.
ör-FinalParametre.java
public class FinalParametre {
        
    public static int topla(final int a , final int b) {
        // a = 5   ! Hata ! 
        // b = 9   ! Hata !
        return a+b;
    }
 
    public static void main(String args[] ) {
          if ( (args.length != 2 )  ) {
            System.out.println("Eksik veri Girildi") ;
            System.exit(-1); // Uygulamayi sonlandir
          }
          int a = Integer.parseInt(args[0]);
          int b = Integer.parseInt(args[1]);
          int sonuc = FinalParametre.topla(a,b);
          System.out.println("Sonuc = " + sonuc );
    }
}
Uygulamamız , dışarıdan iki parametre alarak bunları ilkel olan int tipine çeviriyor.Eğer dışarıdan eksik veya fazla parametre girilmiş ise kullanıcı bu konuda uyarılıyor. Daha sonra elimizdeki değerleri FinalParametre sınıfının statik olan topla() metodu gönderiyoruz. Bu metoda gönderilen parametrelerin değiştirilmesi , final ifadeden dolayı imkansızdır.

Boş (Blank) Final

Java , final olan obje değişkenlerine ilk değeri verme konusunda acele etmez , fakat final olan obje değişkenleri kullanılmadan önce ilk değerlerinin verilmiş olması şarttır.
ör-BosFinal.java
class Kalem { }
 
public class BosFinal {
  final int a = 0; 
  final int b; // Bos final
  final Kalem k; // Blank final obje degiskeni
  // Bos final degiskenler ilk degerlerini 
  // yapilandiricalarda icersinde alirlar
  BosFinal() {
    k = new Kalem();
    b = 1; // bos final degiskenine ilk degeri ver
  }
  BosFinal(int x) {
    b = x; // bos final degiskenine ilk degeri ver
    k = new Kalem();
  }
  public static void main(String[] args) {
    BosFinal bf = new BosFinal();
  }
} 
Boş final değişkenlere değerlerini yapılandırıcıların içersinde vermeliyiz.Bir başka nokta ise statik olan global değişkenler boş final olma özelliğinden faydalanamazlar.

Final Metodlar

Türetilen bir sınıf içersindeki metod tarafından iptal edilme riskini sıfar'a indirmek için , final metodlar yazılabilir. Final metodlar iptal edilemezler.
ör-FinalMetod.java
 
class A {
    public final void ekranaYaz() {
        System.out.println("A.ekranaYaz()");
    }
}
 
class B extends A {
    public void ekranaYaz() {
        System.out.println("B.ekranaYaz()");
    }
}
A sınıfına ait ekranaYaz() metodu , A sınıfından türetilmiş B sınıfının ekranaYaz() metodu tarafından iptal edilemez(overriding) . FinalMetod.java örneğini derlemeye çalıştığımızda aşağıdaki hata mesajını alırız ;
FinalMetod.java:9: ekranaYaz() in B cannot override ekranaYaz() in A; overridden
method is final
    public void ekranaYaz() {
                ^
1 error

private ve final

Final ve private erişim belirliyicisine sahip olan bir metod , başka bir metod tarafından iptal ediliyormuş gibi gözükebilir.
ör-SivilPolis.java
class Polis {
    private final void sucluYakala() { // gorunmez,gizli metod
        System.out.println("Polis.sucluYakala()");
    }
}
 
public class SivilPolis extends Polis {
    public void sucluYakala() { //iptal etme soz konusu degildir
        System.out.println("SivilPolis.sucluYakala()");
    }
}
Private erişim belirliyicisine sahip olan metod , dışarıdan erişilemiyeceğinden dolayı , türetilen sınıflar içersindeki metodlar tarafından iptal edilmesi söz konusu değildir.Private erişim belirliyicisine sahip olan bir metod , bir sınıfın gizli ve özel tarafıdır , o sınıfın arayüzü değildir. Bir sınıfın arayüzleri ,o sınıfa ait public ,protected veya friendly erişim belirliyicilerine sahip olan metodlarıdır.

Final Sınıflar

Bir sınıfı final yaparak , bu sınıftan kalıtım yapılmasını engellemiş oluruz. Bir sınıfın final yapılmasının iki sebebi olabilir, birincisi tasarım , ikincisi ise verimlilik . Final sınıflar komposizyon yöntemi ile kullanabilirler.
ör-Tv.java
final class Televizyon {
    public void kanalBul() {
    }
}
 
/*
class SuperTelevizyon extends Televizyon{
} 
*/
 
class Ev {
    int oda_sayisi = 5 ;
    Televizyon tv = new Televizyon() ;
    public static void main(String args[]) {
        Ev e =  new Ev(); 
        e.tv.kanalBul();
    }
 
}

Kalıtım (Inheritance ) ve ilk değer alma sırası

Diğer programlama dillerinin coğunda , uygulamanın ihtiyaç duyduğu dosyalar tek seferde toplu olarak, uygulamanın başladığı anda yüklenir ve daha sonra ilk değer alma işlemi başlar . Java ihtiyaç duyduğu dosyaları yükleme işlemine daha değişik bir bakış açısıyla bakar.
Javada tüm mantık objeler üzerine kurulmuştur,ve her sınıf kendi fiziksel dosyasında durur.Java bu sınıf dosyalarını,uygulama ihtiyaç duyduğu anda yükleme işlemi başlar.Böylece performans maksimuma çıkartılmış olur.Bir sınıf dosyası ne zaman sınıf yükleyicisi (Class Loader) tarafından hafızaya yüklenir ? Cevap ; eğer bir sınıfa ait statik global değişken veya statik bir metod çağrıldığında , bu sınıf , sınıf yükleyicisi (Class Loader) tarafından yükleni veya bir sınıfa ait bir obje oluşturmak istersek , önce yükleme işlemi gerçekleşir.

İşin içersine Kalıtım kavramı girdiğinde , örneğin B sınıfı başka bir sınıfdan türemiş (B extends A ) ise o zaman yükleme sırasında ana sınıf da hafızaya yüklenir - Hem B sınıfı hemde A sınıfı , sınıf yükleyicisi (Class Loader) tarafından yüklenir..

ör-Bocekcik.java
class Bocek {
        int a = 10;
        int b;
        Bocek() {
               ekranaBas("a = " + a + ", b = " + b);
               b = 17;
        }
        static int x1 = ekranaBas("static Bocek.x1 ilk deger verildi");
        static int ekranaBas(String s) {
               System.out.println(s);
               return 18;
        }
}
 
public class Bocekcik extends Bocek {
        int k = ekranaBas("Bocekcik.k ilk deger verildi");
        Bocekcik() {
               ekranaBas("k = " + k);
                ekranaBas("b = " + b);
        }
        static int x2 = ekranaBas("static Bocekcik.x2 ilk deger verildi");
        public static void main(String[] args) {
               ekranaBas("Bocekcik - basla..");
               Bocekcik b = new Bocekcik();
        }
} 
Uygulamanın çıktısı aşağıdaki gibidir ;
static Bocek.x1 ilk deger verildi
static Bocekcik.x2 ilk deger verildi
Bocekcik - basla..
a = 10, b = 0
Bocekcik.k ilk deger verildi
k = 18
b = 17
Gelişen olayları adım adım açıklarsak ;

Öncelikle Bocekcik sınıfına ait statik bir metod olan main() çağrılıyor (java Bocekcik komutuyla ). Sınıf yükleyici (Class Loader) Bocekcik.class fiziksel dosyasını bulmaya çalışır. Eger bulursa bu sınıf yüklenir, Bocekcik sınıfının bulunduğunu farzedelim , Bu yükleme esnasında Bocekcik sınıfın türetildiği ortaya çıkar ( Bocekcik extends Bocek) . Kalıtım kavramından dolayı Bocek sınıfıda , sınıf yükleyicisi tarafıdan yüklenir (eğer Bocek sınıfıda türetilmiş olsaydi , türetildiği sınıfda yüklenecekti , bu böyle sürüp gidebilir…).

Daha sonra statik olan global değiskenlere ilk değerleri verilmeye başlanır. Değer verme işlemi en yukarıdaki sınıfdan başlar ve türemiş sınıflara doğru devam eder (aşağıya doğru) . Burada en yukarıdaki sınıf Bocek sınıfıdır - (Object sınıfını ihmal edersek ) . Bu sonuçlar göz önüne alındığında ekrana çıkan ilk iki satırın aşağıdaki gibi olması gerekir.
static Bocek.x1 ilk deger verildi
static Bocekcik.x2 ilk deger verildi
Sırada main() metodunun çağrılmasına gelmiştir . Ekrana çıkan üçüncü satır ;
Bocekcik - basla..
Sonra Bocekcik objesi oluşturulur ( Bocekcik b = new Bocekcik() ). Bu oluşturma sırasında ilk olarak en yukarıdaki sınıfa (Bocek sınıfı) ait statik olmayan(non-static) degişkenlere ilk değerleri verilir ve yapılandırıcısı çağrılır. Ekrana çıkan dördüncü satır
a = 10, b = 0

Son olarak Bocekcik sınıfının içersindeki statik olmayan( non-static) değişkenlere ilk değerleri verilir ve Bocecik sınıfının yapılandırıcısı çağrılır.
Bocekcik.k ilk deger verildi
k = 18
b = 17


ve mutlu son …

Yorumlar

Bu blogdaki popüler yayınlar

Java Deger Atama ve Local Değişkenler

Değişkenlereilk değerlerini atama Javauygulamalarında üç tür değişken çeşiti bulunur , yerel (local) değişkenler, obje'ye ait global değişkenler ve son olarak sınıfa aitglobal değişkenler(statik değişkenler). Bu değişkenlerin tipleri ilkel(primitive) veya herhangi bir obje tipi olabilir. ör-javada-degiskenler public class DegiskenGosterim {int x ; //objeye ait global degiskenstatic int y ; // sınıfa ait global degiskenpublic void metod () {int i ; //yerel degisken//static int y = 5 ;// yanlis}} Yerel(local)değişkenlerYereldeğişkenlere kesin olarak ilk değerleri kodu yazan kişi tarafındanverilmelidir. İlk değeri verilmeden kullanılan yerel değişkenlere uyarı ,derleme(compile-time) anında verilir. gösterim-11 public int hesapla () { // yerel değişkenlere ilk değerleri her zaman verilmelidir.int i ; i++; // ! Hata ! ilk deger verilmeden üzerinde işlem yapılamazreturn i ;} Objeyeait global değişkenlerObjelereait global değişkenler'e ilk değerlerini kodu kişi vermek zorunda değildir.Ja…

Anakart ve Bileşenleri Nelerdir?

Anakart
Mainboard olarak da adlandırılır. Sistemdeki bütün kartların, işlemcinin üzerine takıldığı, diğer donanım aygıtlarının kablolar vasıtasıyla bağlandığı ve bilgisayarın en karmaşık parçalarından biridir.
Anakart Bileşenleri
1. İşlemci soketi: İşlemcinin takıldığı sokettir.
2. Bellek soketi: RAM denilen sistem belleğinin takıldığı soketdir.
3.Genişleme Yolları Anakart üzerine ekran kartı, modem, ses kartı, vs gibi parçalar anakart üzerindeki genişleme yuvaları ya da veri yolu yuvaları denilen soketlere takılır. Yani kartların işlediği veriler ve kartlara giden bilgiler, bu yuvalar ve anakart üzerindeki veri yolları aracılığı ile işlemciye ve diğer aygıtlara ulaşırlar.
4. Güç Konnektörleri(Güç kaynağı girişi): Anakart üzerine güç kaynağından gelen kablolar bu konnektörlere bağlanır.
5. Klavye/Fare Konnektörleri(portları): Klavye ve fare yuvarlak 6 pinli bir fiş (PS/2 fişi) kullanılarak anakartaki klavye ve fare portlarına bağlanır.
6. Yonga Setleri (Chipsets): Bilgisayarların trafik pol…

Örnek Java Kodları

Java Örnekler:...

1. Ekrandan girilen n*m matrisin istenilen satırların toplamını veren java programını yazınız.

Java Kodu 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package odev1.matris;
import java.util.Scanner;
/**
 *
 * @author aycan
 */
public class Odev1Matris {


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        Scanner keybord  = new Scanner(System.in);
        int satir,sutun,cevap;


        System.out.println("Matrisin Satır Sayisini Giriniz ");
        satir= keybord.nextInt();
        System.out.println("Matrisin Sutun Sayisini Giriniz ");
        sutun= keybord.nextInt();

        int[][] matris = new int[satir+2][sutun+2];
        int [] top = new int[satir+2];

        for(int i=1 ;i<=satir ; i++ )
            for(int j =1 ; j <=sutun ;j++)
            { System.out.println("Girmis oldugunuz matrisini( "+i+","+j+" )giriniz");
  …