Słowo kluczowe var

Java ze swej natury jest językiem statycznie typowanym. Oznacza to, że musimy określić typ zmiennej, którą definiujemy, np.:

int x = 5;
String name = "Jan";

Wiele języków, takich jak np. JavaScript oferują dynamiczne typowanie, czyli nie musimy wskazywać jakiego typu będzie nasza zmienna. Co więcej nie jest problemem to, że do zmiennej, do której najpierw przypisaliśmy np. liczbę po chwili przypiszemy napis, np.:

var x = 5;
x = "Jan";

Oczywiście istnieją zwolennicy jednego i drugiego podejścia, ale biorąc pod uwagę, że dla JavaScriptu powstają alternatywy takie jak TypeScript, w którym główna różnica polega właśnie na statycznym typowaniu, to nie da się ukryć, że wielu programistów docenia kontrolę typów, która pozwala pisać kod bardziej odporny na błędy.

Słowo var w Javie 10

Java 10 nie wprowadziła wielu nowości z punktu widzenia kodu, ale pojawiło się nowe słowo var. Co ciekawe nie jest to zastrzeżone słowo kluczowe tak jak np. int, void itp. ale tylko zarezerwowana nazwa typu. Oznacza to tyle, że słowa var nadal możemy używać do nazw swoich zmiennych, czy metod i takie rozwiązanie wynika właśnie z kompatybilności wstecznej. Od Javy 10 możemy więc zdefiniować taką zmienną:

var var = 5;

Słowo var a dynamiczne typowanie

Słowa var nie należy utożsamiać z jego odpowiednikiem z języka JavaScript. Nie wprowadza ono do Javy dynamicznego typowania, a jego głównym założeniem jest skrócenie deklaracji zmiennych lokalnych, których typem są jakieś typy obiektowe o długich nazwach.

Przykładowo do odczytu danych z pliku popularną konstrukcją w Javie jest użycie klasy BufferedReader co wygląda mniej więcej tak:

FileReader fr = new FileReader("plik.txt");
BufferedReader reader = new BufferedReader(fr);

Od Javy 10 zapis ten można skrócić do:

var fr = new FileReader("plik.txt");
var reader = new BufferedReader(fr);

Typ zmiennych fr i reader zostanie wywnioskowany na podstawie tego co do nich przypisujemy (z angielskiego nazywa się to "local variable type inference").

Ważne jest to, że var nie sprawia, że zmienna staje się nagle "dynamiczna". Tzn. poprawne jest przypisanie do zmiennej zadeklarowanej z użycie słowa var nowej wartości tego samego typu co pierwotnie, np.:

var name = "Jan";
name = "Karol";

ale nie można do takiej zmiennej przypisać wartości innego typu, np.:

var name = "Jan";
name = 123; //błąd Incompatybile types

Kiedy używać słowa var

Nie wszędzie. Choć wydaje się to fajnym rozwiązaniem i istnieje pokusa, żeby teraz wszędzie zapisywać tylko var, var, var, to w rzeczywistości nie należy nadużywać tej funkcjonalności. Słowo var bardzo mocno wymusza poprawne nazewnictwo zmiennych. Oprócz tego co dana zmienna robi, dobrze byłoby w nazwie dodać także nawiązanie do typu. Spójrz na taki fragment kodu:

public static void main(String[] args) {
    var x = longMethodName();
    System.out.println(x);
}

static int longMethodName() {
    return 5;
}

Patrząc na samą metodę main nie mamy pojęcia co tak naprawdę reprezentuje x. Dużo lepiej zastosować w tym konkretnym przypadku klasyczny zapis:

public static void main(String[] args) {
    int x = longMethodName();
    System.out.println(x);
}

static int longMethodName() {
    return 5;
}

szczególnie, że ilość kodu jest identyczna. Słowa var używaj więc tylko w sytuacjach, kiedy tworzysz obiekt, którego typ ma długą nazwę, tak jak we wcześniejszym przykładzie z BufferedReaderem.

Ograniczenia

Słowa var na chwilę obecną można używać wyłącznie do zmiennych lokalnych. Jest to związane z tym, że w ich przypadku mamy gwarancję tego, że typ będzie mógł być wywnioskowany na etapie kompilacji (zmienne lokalne muszą być jawnie zainicjowane, nie mogą zostać "puste"). Ma to sens. ponieważ w sytuacji, w której zdefiniowalibyśmy metodę o takiej sygnaturze:

int longMethodName(var arg1, var agr2){...}

ani kompilator ani wirtualna maszyna raczej nie byłyby w stanie wywnioskować jakiego typu argumenty ktoś będzie mógł nam przekazać, a tym samym jakie operacje będzie można wykonać w ramach metody na arg1 i arg2.

Podsumowanie

Słowo var jest raczej zmianą kosmetyczną, tzw. lukrem składniowym. Nie wprowadza wielkiej rewolucji do tego jak będziemy pisali nasz kod w Javie (tak jak było to np. z wyrażeniami lambda, które praktycznie wyeliminowały klasy anonimowe). Jeżeli mamy zamiar z nich korzystać, to warto zachować umiar, ponieważ paradoksalnie mogą prowadzić do zaciemnienia kodu.

Dyskusja i komentarze

Masz pytania do tego wpisu? Może chcesz się podzielić spostrzeżeniami? Zapraszamy dyskusji na naszej grupie na Facebooku.