"Enter"a basıp içeriğe geçin

JAVA – “final” anahtarı hakkında her Java programcısının bilmesi gereken 10 nokta.

Java’da final anahtarı sınıflarla, değişkenlerle ve metotlarla birlikte kullanılabilir. final anahtar kelimesi kullanıldığı üyenin değişikliğe uğramasını engeller. Yani final anahtarı sınıf, değişken veya metot ile birlikte kullanıldığında bu üyeler oluşumlarının ardın değiştirilemezler.

Bu makale ile final anahtarı hakkında 10 adet önemli noktaya değineceğiz. Makalemize final anahtarı hakkında bazı basit şeylerden bahsederek başlayalım.

Java’da final class:

“final class” başka bir class’ı genişletmek için kullanılamaz.

final class FinalClass {
    //diğer ifadeler
}
 
class AltSınıf extends FinalClass {
    //compile time error
    //final class'ı kullanılarak bir alt sınıf oluşturulamaz.
}

Java’da final metotlar:

final olarak tanımlanmış bir metot, alt class içerisinde override edilemez.

class SuperClass {
    final void metotBir() {
        //diğer ifadeler
    }
}
 
class AltSinif extends SuperClass {
    @Override
    void metotBir() {
        //Compile time error
        //final metotlar override edilemezler
    }
}

Java’da final değişkenler:

final olarak tanımlanmış bir değişkenin değeri sonradan değiştirilemez.

class HerhangiBirSinif {
    final int i = 10;
 
    void metotBir() {
        i = 20;     //compile time error
        //final değişkenlere yeniden değer atanamaz
    }
}

Bu kısa bilgilerin ardından asıl konumuza dönebiliriz. “final” anahtarı hakkında her Java programcısının bilmesi gereken 10 noktayı madde madde açıklayarak makalemize devam edelim.

  1. Herhangi bir sınıf veya her hangi bir metot abstract veya final olarak tanımlanabilir. Ancak her ikisini aynı anda kullanamayız. Zaten bu durum mantık olarak da hatalıdır. Abstract olarak tanımlanmış üyeler değişiklik yapılması zorunda olan üyelerdir. final ise değişikliği kısıtlayan bir anahtardır. Yani tutarsızlık oluşur. Bu nedenle böyle bir tanımlama yapmak istediğinizde derleme zamanı hatası alırız.
//Aşağıdaki sınıf derleme zamanı hatası verir.
 
final abstract class HerhangiBirSinif {
    //Hiçbir sınıf aynı anda abstract ve final olarak tanımlanamaz.
 
    final abstract void metotBir();
    //metotlar aynı anda final ve abstract olarak tanımlanamazlar.
}

2. final olarak tanımlanmış bir metot aşırı yüklenebilir (Overloading). Aşırı yüklenmiş bu metot alt sınıf içerisinde ezilebilir (Overriding).

class SuperClass {
    final void metotBir() {
        //final metot
    }
 
    void metotBir(int i) {
        //final metodun aşırı yüklenmesi
    }
}
 
class AltSinif extends SuperClass {
    @Override
    void metotBir(int i) {
        //aşırı yüklenmiş metot override ediliyor.
    }
}

3. final değişkenlere yeniden değer atanamaz ancak bu değişkenler yeni oluşturulacak diğer değişkenleri initialize ederken kullanılabilir.

class HerhangiBirSinif {
    final int i = 10;
 
    void metotBir() {
        i++;
        //yukarıdaki ifadede derleme zamanı hatası oluşur.
        //final değişkeninin değeri değiştirilemez.
 
        int j = i;        //final değişken başka bir nesneye değer atanırken kullanılabilir.
 
        System.out.println(i);  //final değişken kullanılıyor.
    }
}

4. Bir array final olarak tanımlanırsa, array içersindeki değerler değiştirilebilir. Ancak arrayin kendisi değiştirilemez.

public class FinalAnahtarininKullanimi {
    public static void main(String[] args) {
        final int X[] = new int[10];     //final array değişkeni
 
        X[2] = 10;
        X[2] = 20;     //array elamanlarına yeniden değer atanabiliyor.
 
        X = new int[30];  //compile time error
        //Array nesnesinin kendisi değiştirilemez.
    }
}

5. Bir sınıfın final olarak tanımlanmış bir örneği oluşturulabilir. Bu durumda örnek nesne direkt olarak değiştirilemezken, örnek içindeki diğer değişkenlerin değerleri değiştirilebilir.

class A {
    int i = 10;
}
 
public class FinalAnahtarininKullanimi {
    public static void main(String[] args) {
        final A a = new A();  //final reference variable
 
        a.i = 50;
        //final olarak tanımlanmış bir nesnenin içindeki normal bir değişkenin değeri değiştirilebilir.
 
        a = new A();  //compile time error
 
        //final olarak tanımlanmış bir nesnenin direkt kendi değeri değiştirilemez.
    }
}

6. Statik değişkenler, statik olmayan değişkenler ve lokal değişkenler final olarak tanımlanabilirler. Ancak bu final değişkenlere intialize olduktan sonra tekrar değer atanamaz.

class A {
    static final int i = 10;   //final statik değişken
    final int j = 20;          //final statik olmayan değişken
 
    void metotBir(final int k) {
        //k bir lokal final değişkendir.
        k = 20;   //compile time error
    }
}
 
public class FinalAnahtarKullanimi {
    public static void main(String[] args) {
        A a = new ();
 
        a.i = 10;     //Compile time error
        a.j = 20;     //yeniden değer atanamaz.
 
        a.metotBir(20);
    }
}

7. Önceki makalelerimizde de bahsettiğimiz gibi, global değişkenler initialize edilmese bile varsayılan değerler alır. Ancak final olarak tanımlanmış bir global değişken varsayılan değer almaz. Bu nedenle nesne oluşturulurken bu değişkenlere değer ataması yapılmalıdır. Aşağıdaki örneği inceleyerek net bir fikre ulaşabilirsiniz.

class A {
    int i;   //normal global değişken. initialize edilmesine gerek yoktur.
 
    final int j;         //Boş Final Alan
 
    A() {
        j = 20;
 
        //final global değişkenlere değerleri, nesne oluşturulurken atanmanmalıdır..
    }
}
 
public class FinalAnahtarKullanimi {
    public static void main(String[] args) {
        A a = new A();
    }
}

8. final olarak tanımlanmış, statik olmayan final değişkenler, bütün constructorlar veya bütün IIB blokları içerisinde sadece biri tarafından initialize edilmelidir.

class A {
    final int i;  //final olarak tanımlanmış statik olmayan değişkenlere değerleri burada veya
    //herhangi bir IIB bloğu içersinde atanabilir,
    // çünkü bir nesnenin oluşması için bütün IIB bloklarının açılışmış olması gerekmektedir. Veya
 
    {
        i = 30;
    }
 
    {
        //i = 40;
    }
 
    //Her hangi bir constructor içinde değer atanmalıdır.
    //çünkü bir nesnenin oluşması için bütün yapıcı metotların çalıştırılmış olması gerekmektedir.
 
    A() {
        //i=20;
    }
 
    A(int j) {
        // i=j;
    }
 
    A(int j, int k) {
        // i = 50;
    }
}

9. Global olarak tanımlanmış final static değişkenlere ya tanımlama sırasında yada SIB lar içersinde değer verilmelidir. Global olarak tanımlanmış final statik değişkenlere constructor içinde değer atanamaz.

class A {
    static final int i;   //final static global değişkene burada veya bir tane SIB içersinde değer atanabilir.
    
    static {
        i = 30;
    }
 
    static {
        //i = 40; //ikinci değişiklik yapılamaz
    }
 
    //final static global değişkenlere constructor'lar içinde değer atanamaz.
 
    A() {
        //i=20;
    }
 
    A(int j) {
        //i=j;
    }
 
    A(int j, int k) {
        //i = 50;
    }
}

10. Global bir değişken final ve static olarak tanımlanırsa çalışma anında değerleri değiştirilemez. Çünkü statik değişkenler class hafızasında tutulurlar ve class dan üretilen bütün örneklerinde statik değişkenlerin değerleri değişmez. dolayısı ile alt sınıflar içinden değerlerinin değiştirilmesi mümkün değildir.

İlk Yorumu Siz Yapın

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir