Java final İfadesi Nedir? Ne İçin Kullanılır?
final keyword, tıpkı static ifadesi gibi Java tarafından belirli amaçlarla geliştirilmiş fonksiyonel bir sözcüktür. Bu sözcük, Java’daki pek çok yapı ile birlikte kullanılmakta ve kullanıldığı yerde farklı fonksiyonlar icra etmektedir. Bu yazıda sizlerle birlikte final ifadesini yakından inceleyecek ve final kelimesinin class, method ve variable’larla kullanımına değineceğiz.
final Nedir? Ne İçin Kullanılır?
Java’da final, sizin de tahmin edebileceğiniz üzere sabitleri belirtmek ve onların değişimlerini önlemek amacıyla oluşturulan bir sözcüktür. Bir diğer ifade final, bir yapının nihai halini aldığını ve onu değiştirmenin, dönüştürmenin veya ondan bir şeyler türetmenin mümkün olmadığını göstermek ve bunu sağlamak için kullanılır. final keywordü, sınıflar (class), metodlar (method) ve değişkenlerle (variable) birlikte kullanılabilir. Bu üç farklı kullanımda da final ifadesinin yerine getirdiği, sebep olduğu farklı fonksiyonlar mevcuttur.
final Variable (final değişken)
Bir değişken yani variable final olarak bildirildiği vakit, onun değeri hiç bir şekilde değiştirilemez. O artık bir sabit haline gelmiş ve nihai değerini almıştır. Bu değiştirilmeye çalıştırıldığında Java hata verecektir.
Bir değişkeni final olarak bildirmeden önce ona bir değer atamak yani initialization işlemi yapmak gerekir. Genel kural bu şekildedir. Bununla birlikte değişkeni final olarak belirledikten sonra da değer atamak mümkündür.
Bir metodun, constructor’un veya block’un içerisinde oluşturulmuş variable’lara local variable denir. Bu tür variable’lara oluşturuldukları yerde, sonradan değer atamak mümkündür. Dolayısıyla aşağıda bahsettiğimiz istisnalar instance variable’ları için geçerlidir.
Herhangi bir değer atamadan oluşturlan final değişkenlere blank final variable denir. Bu tür variable’ları constructor içerisinde, instance initializer block içerisinde ve static block içerisinde initialize etmek yani değer ataması yapmak mümkündür.
Aşağıda her birinin bir örneğini görebiliriz.
class OrnekClass {
// initialize edilmiş bir final variable
final int hizSiniri = 150;
// ilk blank final variable
final int kapasite;
// ikinci blank final variable
final int uzunluk;
// initialize edilmiş static final variable
static final double pi = 3.141592653589793;
// static blank final variable
static final double genislik;
// kapasite değişkenini initialize etmek için
// oluşturulmuş instance initializer block
{
kapasite = 100;
}
// genislik değişkenini initialize etmek için
// oluşturulmuş static initializer block
static{
genislik = 2.3;
}
// uzunluk değişkenini initialize etmek için
// oluşturulmuş bir Constructor.
public OrnekClass()
{
uzunluk = -1;
}
}
final değişkenler ile normal değişkenler arasındaki tek fark, final değişkenlerin, sabit ve nihai hallerini almış olmaları ve atandıktan sonra değiştirilememeleridir. Bu sebeple, program boyunca değişmesini istemediğimiz değişkenleri final olarak bildirebiliriz.
Reference final variable:
Yukarıda da ifade ettiğimiz gibi final variable’lara yeni değer atamak değildir. Fakat final olarak bildirilen bir variable ‘reference variable’ ise yani bir class, array vb. gibi heap memory’de yer alan bir nesne veya değere işaret ediyorsa, yeni değer atamadan, içerisinde değişiklikler yapmak mümkündür. String Builder, Array vb. yapılarda bu işlem gerçekleştirilebilir.
// Örnek 1:
final StringBuilder testingDev = new StringBuilder("Testings");
testingDev.append(".Dev");
System.out.println(testingDev); // Output: Testings.Dev
// Örnek 2:
final int[] arr = {1,2,3};
arr[0] = 5;
System.out.println(Arrays.toString(arr)); // Output: [5, 2, 3]
final Metod
Tıpkı bir değişkende yaptığımız gibi bir metodu da final olarak deklare edebiliriz. Bunun için metodun return type’ından önce final yazmak yeterlidir. final keyword tıpkı variable’da olduğu gibi metodlarda da bir takım sınırlama ve kısıtlamalara yol açar.
Tıpkı variable’larda olduğu gibi final bir metod değiştirilemez, dolayısıyla final metotlar bir child veya subclass tarafından override edilemezler. Yani parent bir class’ta oluşturduğumuz metodun, alt class’lar tarafından override edilmesini yani değiştirilmesini istemiyorsak, onu final olarak bildirebiliriz.
final void ornekMetod() {
System.out.println("Testins.dev");
}
final Class
Variable ve Class’ları final olarak belirleyebildiğimiz gibi class’ları da final olarak belirleyebiliriz. Bir class’ı final olarak belirlediğimizde onu bir nevi kısırlaştırmış oluruz. Zira bir class’ı final olarak belirledikten sonra ona child class atamak, yani onu parent class yapmak mümkün olmaz. Bir diğer değişle herhangi bir class, final class’a extend edilemez.
final class Ornek {}