Var

Zarezerwowany typ o nazwie var wprowadzony w Javie 10 jako jeden z rezultatów projektu Amber. Został już dość dobrze opisany na innych mądrych stronach, zatem przytoczę tylko nieoczywiste fakty na jego temat.

var może wpływać na bytecode

Całe wnioskowanie typu dzieje się na etapie kompilacji do bytecode’u. Wtedy również dzieje się podmiana typu zmiennej na typ wywnioskowany.

Czasem przy definicji zmiennej użylibyśmy interfejsu. Jednak gdy użyjemy słowa var, wówczas w pewnych użyciach w bytecodzie pojawi się typ konkretny. Przykładowo w takim kawałku kodu:

        List<String> list = new ArrayList<>();
        list.size();

        var varList = new ArrayList<String>();
        varList.size();

Dekompilowanie poleceniem javap -v -p potwierdza tę tezę:

      LocalVariableTable:
        Start  Length  Slot  Name   Signature
(...)
           16     113     2  list   Ljava/util/List;
           31      98     3 varList   Ljava/util/ArrayList;
(...)

Z tej różnicy wynika konieczność użycia instrukcji invokeinterface zamiast invokevirtual. W trybie interpretowanym invokeinterface ma potencjalnie niezerowy (ale i niezbyt duży) negatywny wpływ na wydajność. Ale o tym już pisałem, więc nie będę rozwijał tego wątku…

var umożliwia wywoływanie metod wcześniej niewidocznych…

… i nie tylko chodzi o to, że w poprzednim przykładzie można wywoływać metody typowe dla konkretnej klasy. Chociaż poniekąd jest to powiązane…

Otóż wyobraźmy sobie klasę anonimową. Standardowo nie mamy informacji o tym, jaka to jest klasa, ponieważ jest… anonimowa… Jednak używając słowa var można wywołać metody specyficzne dla tej klasy.

        var anonymous = new Object() {
            int anInt;
            public int ret() {
                return anInt;
            }
        };
        anonymous.anInt = 4;
        System.out.println(anonymous.ret());

Pachnie Javascriptem, co nie? 😉
Co by nie mówić, wcześniej wywoływanie metod klas anonimowych było możliwe tylko z użyciem refleksji lub methodHandle, więc jest to jakieś usprawnienie.

Czytelność

Dyskusyjną sprawą jest czytelność. Osobiście w jednym projekcie pisanym w Javie 11 doświadczyłem, że var może tę czytelność poprawić. Przykładowo, osobiście taki kod łatwiej się czyta:

var stringsByIds = getStringsById();
var stringList = stringsByIds.getOrDefault(1, List.of());

// zamiast:
Map<? extends Serializable, List<? extends String>> stringsByIds = getStringsById();
List<? extends String> stringList = stringsByIds.getOrDefault(1, List.of());

var w tym przypadku ułatwia nam zrozumienie „co się tu dzieje”. Analizy „jak się to dzieje” raczej nie zaciemnia, bo i tak aby zrozumieć trzeba ponawigować trochę po klasach.

Unikałbym jednak słowa var przy typach prymitywnych z zainicjalizowaną wartością.

        var l = 1; // czy to long?
        var f = 1.0; // czy to float?

Final?

Jak sprawić by nasza zmienna była zmienną ostateczną? Używając final var.

Były proponowane różne podejścia do tego zagadnienia – między innymi była propozycja słowa val lub let. Niestety ostatecznie nie zdecydowano się na wprowadzenie do Javy żadnego z tych słów…

Podsumowanie

var może być przydatny 😉
Podrzucam też bezpośredni JEP odnośnie var oraz podsumowanie dyskusji na temat obecnego kształtu tego słówka.

P.S. Wiem, że czyta ten blog niezerowa liczba osób, ale jeszcze nie dorobiłem mechanizmu, sprawdzającego, ilu się udaje doczytać do końca… Zatem taka prośba: jeżeli doczytaliście aż dotąd, zostawcie po sobie ocenę lub komentarz. Będę wtedy wiedział, że da się te wypociny doczytać do końca 😉

Pax

Oceń wpis

Autor: jgardo

Programista Java od 2013 roku. Interesuje się niskopoziomową Javą, ekosystemem Jvm i jego wydajnością. Co jednak nie przeszkadza w przywiązywaniu uwagi do czystości kodu w życiu codziennym ;) Pracuje w PayU.

Jedna myśl w temacie “Var”

  1. Cześć, doczytałem do końca.

    Blog ciekawy, porusza tematy raczej nieobecne na innych blogach, zwłaszcza polskojęzycznych

     

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *