Oktay Uğurlu
Yazılım Geliştirme Uzmanı

Java 17: Local-Variable Type Inference

Java 17: Local-Variable Type Inference

Local-Variable Type Inference özelliği Java 10 ile birlikte gelmiştir. JavaScript dilindeki gibi variable tanımlaması yaparken local type inference için kullanılan ve variable’ı istediğiniz tipte tanımlamanızı sağlayan bir Java anahtar kelimesidir. “var” kullanımı özellikle çok uzun variable tanımlamaları yerine kullanımı kodun okunurluğu açısından fayda sağlar. Örnek bir variable tanımını aşağıda görebilirsiniz:

var map=new HashMap<String,String>();

Burada var ile ilgili dikkat edilmesi gerekilen hususlar aşağıda listelenmiştir:

1- JavaScript dilinin aksine, Java dilinde tanımlanan her şey statik tiptedir. Bu yüzden, var ile tanımlanan bir variable için aynı scope’da başka type’da değer atanamaz:

1
2
var id = 0; // Compiler burada id variable’ını 0 olarak atar.
id = "34"; // Burada aşağıdaki gibi bir compile time hatası alırız

2- Java dilindeki diğer special keyword’lerin aksine, var keyword’u reserved keyword olarak geçmez. Bu yüzden identifier olarak kullanılabilir:

1
2
3
var var = 0; 

System.out.println(var); // 0

3- Eğer var keyword kullanacaksanız, her zaman variable’ınızı initialize etmeniz gerekir. Yani var ile tanımlanan bir variable hiçbir zaman null olamaz:

1
2
var number; // Compiler hatas: Cannot infer type: 'var' on variable without initializer 
var number = null; // Compiler hatası: Cannot infer type: variable initializer is 'null'

4- Eğer var ile tanımlanan variable bir subclass olarak initialize edilmiş ise, daha sonrasında ortak parent class’tan extend etmiş başka bir class objesi atanamaz. Örneği Employee sınıfını extend eden iki tane Manager ve Developer sınıfı olsun:

1
2
3
class Employee {}
class Developer extends Employee {}
class Manager extends Employee {}

Sonrasında şu şekilde iki tanımlama yapalım:

1
2
3
4
Employee employee= new Developer(); // Java’nın inheritance özelliği bunu sağlar
employee = new Manager();         
var employee= new Developer(); // Fakat aynı tanımı var ile yapamayız; Compilation error: incompatible types: Manager cannot be converted to Developer
employee = new Manager();

5- Fakat parent class ile initialize edilmiş bir variable’a geri subclass atayabilirsin:

1
2
var employee = new Employee();
employee = new Manager(); // Çalışır

6- var keyword sadece local variable initialization için kullanılabilir:

1
2
3
class Employee {
    var name = Oktay; // Compiler error: Cannot resolve symbol ’var’ 
}

7- 4. Maddede bahsettiğimiz gibi, var ile tanımlanmış bir variable her zaman anında initialize edilmesi gerektiği için, metot parametrelerinin tanımlanmasında kullanılamaz:

public long countNumberofFiles(var fileList);// Compilation error: cannot use 'var' on variable without initializer

8- Java 11 ile birlikte, lambda expression’ların parametre tanımlamaları için var keyword kullanılabilir hale geldi:

Örnek 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
public void explicitTypes() {
    var Roland = new Person("Roland", "Deschain";
    var Susan = new Person("Susan", "Delgado");
    var Eddie = new Person("Eddie", "Dean");
    var Detta = new Person("Detta", "Walker");
    var Jake = new Person("Jake", "Chambers");
    var filteredPersons =
         List.of(Roland, Susan, Eddie, Detta, Jake)
                   .stream()
                   .filter((var x) -> x.name.contains("a")) // x’in type’ı Person olarak compiler tarafından bilinebilir
                   .collect(Collectors.toList());
    System.out.println(filteredPersons);
}

Örnek 2:

1
2
3
4
5
6
7
8
9
interface Drawable{
        boolean draw(String name);
}

public void main(){
    Drawable m = (var x) -> x.contains("a");
    boolean deger = m.draw("Merhaba");
    System.out.println(deger); // true    
}

9- var ile tanımlanmış bir variable’a lambda expression atanamaz, çünkü lambda expressionların kendisi de aslında belli bir type’a sahip olmadığı için hangi type olduğunu atandığı variable type’ından veya return edildiği metoddan alır:

1
var z = () -> {} // Compilation error because compiler cannot infer type for local variable z; lambda expression needs an explicit target type`

10- var keyword sadece variable tanımlamalarında kullanılabilir. Bu yüzden metotların return type’ı olarak kullanılamazlar:

1
2
3
public var getNumber(){ // Compiler error: Cannot resolve symbol 'var'
     return 0;  
}

Referanslar: