CodeGym /Kursy Java /Moduł 1 /Wnioskowanie typu kompilatora Java

Wnioskowanie typu kompilatora Java

Moduł 1
Poziom 16 , Lekcja 5
Dostępny

1. Cukier syntaktyczny

Programiści uwielbiają, gdy jakiś złożony kod lub logikę można napisać w kilku wierszach, a kod jest zwarty i czytelny. Czasami pomagają im w tym programiści językowi.

Trudne cechy języka, które pozwalają na krótszą ścieżkę (mniej pisania kodu), nazywane są cukrem składniowym . Chociaż, szczerze mówiąc, w Javie jest go bardzo mało.

Twórcy Javy dołożyli wszelkich starań, aby wyeliminować wszelkie możliwe redundancje z Javy. Jeśli w C++ istnieje dziesięć sposobów zrobienia czegoś, w Javie najczęściej jest tylko jeden sposób.

Ale ani programistom Javy, ani twórcom Javy nie podoba się to ujednolicenie. A czasami ułatwiają życie zwykłym facetom, takim jak ty i ja.

Nawiasem mówiąc, zapoznałeś się już z rzeczą, którą można przypisać cukierowi syntaktycznemu - są to autoboxing i unboxing . Porównywać:

Długi kod zwarty kod
Integer a = new Integer(5);
int b = a.intValue();
Integer a = 5;
int b = a;
int b = 5;
Integer c = new Integer(b);
int b = 5;
Integer c = b;
Integer a = new Integer(1);
int b = 1;
if (a.intValue() == b)
{
   ...
}
Integer a = 1;
int b = 1;
if (a == b)
{
   ...
}

Zamiast długiego kodu, jak po lewej, możesz napisać bardziej zwarty kod, jak po prawej. A inteligentny kompilator Javy na podstawie krótkiego kodu wygeneruje jego pełną wersję. To jest cukier składniowy.


2. Wnioskowanie o typach zmiennych −var

W Javie 11 kompilator stał się jeszcze inteligentniejszy i może teraz wywnioskować typ tworzonej zmiennej na podstawie typu wartości, która jest do niej przypisana. W kodzie wygląda to tak:

var Nazwa = oznaczający;

Gdzie Nazwato nazwa nowej zmiennej, wartość  to jej wartość początkowa i varsłowo kluczowe użyte do zadeklarowania zmiennej. Typ nazwy zmiennej będzie  taki sam jak wartość, która jest do niej przypisana.

Przykłady:

Jak widzimy ten kod? Co widzi kompilator
var i = 1;
int i = 1;
var s = "Cześć";
String s = "Cześć";
var console = new Scanner(System.in);
Scanner console = new Scanner(System.in);
var list = new ArrayList<String>();
ArrayList<String> list = new ArrayList<String>();
var data = new int[]{1, 2, 3};
int[] data = new int[]{1, 2, 3};

Sam kompilator określa lub, jak to się mówi, wnioskuje o typie zmiennej na podstawie przypisanej jej wartości.

Wiele egzemplarzy zostało zepsutych w bitwach programistów na temat tego, czy dodać taką funkcję do języka, czy nie. Wielu obawiało się, że użycie varzostanie nadużyte, a czytelność kodu zostanie znacznie zmniejszona.

Jest w tym trochę prawdy, dlatego najlepiej jest stosować vartam, gdzie poprawia czytelność kodu. Na przykład te w dwóch przypadkach:

Przypadek 1: patrząc na wartość zmiennej, od razu wiadomo, jaki typ ma zmienna

Kod Wyjaśnienie
var stream = url.getInputStream();
Zmienna ma typInputStream
var name = person.getFullName();
Zmienna ma typString

Ale w takich przypadkach var nie powinieneś używać . Cóż, odpowiedz, jakiego typu jest zmienna?

Kod Wyjaśnienie
var result = task.execute();
Typ zmiennej jest trudny do określenia
var status = person.getStatus();
Typ zmiennej jest trudny do określenia

Przypadek 2: Typ zmiennej nie jest ważny dla zrozumienia kodu

Często w kodzie mogą wystąpić sytuacje, gdy na zmiennej nie są wywoływane żadne metody - zmienna służy po prostu do tymczasowego przechowywania czegoś. Używanie vartutaj wcale nie zmniejsza zrozumienia kodu:

Długi kod zwarty kod
var data = stream.getMetaData();
storage.save(data)
Otrzymaliśmy metadane ze strumienia streami przechowaliśmy je w magazynie storage. Nie ma znaczenia , jakiego typu była zmienna data.

złoty środek

Teraz podam trzy sposoby na napisanie tego samego kodu. Użycie varbyłoby najlepszą opcją.

Kod Notatka
dest.writeHeaderInfo(src.getFileMetaInfo());
Zbyt zwarty
var headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Doskonały
FileMetaInfo headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Zbyt szczegółowe

headerInfoKiedy przeszliśmy z opcji w linii 1 do opcji w linii 2, dodaliśmy trochę czytelności do kodu kosztem nazwy zmiennej ( ). Teraz jest jasne, że metoda zwróciła nie tylko metainformacje, ale także informacje nagłówkowe.

Trzecia opcja byłaby zbędna. No i co z tego, co headerInfoma typ FileMetaInfo– to już było prawie jasne z getFileMetaInfo(). Cel tych meta-informacji jest znacznie bardziej interesujący.



3. Pominięcie typu - operator diamentu:<>

Jeszcze przed pojawieniem się operatora varpodejmowano próby nauczenia kompilatora wnioskowania o typach kolekcji. Zgadzam się, ten wpis wygląda na nieco zbędny:

ArrayList<String> list = new ArrayList<String>();

Począwszy od siódmej wersji Javy, podczas pisania typu kolekcji można było pominąć (nie zapisywać) typ elementów kolekcji, jeśli został on określony przy deklaracji zmiennej. Te. Powyższy kod można zapisać w nieco skróconej formie:

ArrayList<String> list = new ArrayList<>();

Jak widać, nie ma potrzeby ponownego pisania typu String. Nie tak fajnie jak z operatorem var, ale kiedyś wydawało się to osiągnięciem.

Puste nawiasy trójkątne w typie kolekcji nazwano operatorem rombu : dwa nawiasy niejasno przypominały sylwetkę rombu.

Nie jest pożądane jednoczesne używanie operatora diamentu :var

var list = new ArrayList<>();

Brak informacji o typie przechowywanym w kolekcji, a typ zostanie zdefiniowany jako ArrayList <Object> .



4. Podwójne nawiasy klamrowe

Pamiętasz szybką inicjalizację macierzy?

Właśnie wymieniliśmy tam wartość w nawiasach klamrowych:

Przykłady
int[] data = new int[] {1, 2, 3, 4, 5, 6, 7};
int[] data = {1, 2, 3, 4, 5, 6, 7};

Twórcom Javy spodobał się pomysł wykorzystania nawiasów klamrowych w celu ułatwienia przechowywania danych w tablicy. Ale co ze zbiorami?

Również w przypadku kolekcji wystarczyło wyobraźni: pozwoliły na zastosowanie sztuczki z podwójnymi nawiasami klamrowymi.

Z cukrem Bez cukru
var list = new ArrayList<String>()
{{
   add("Cześć");
   add("Jak");
   add("Дела");
}};
var list = new ArrayList<String>();

list.add("Cześć");
list.add("Jak");
list.add("Дела");

Jeśli kompilator napotka kod w przykładzie po lewej stronie, przekonwertuje go na kod po prawej stronie.

Kod nie staje się dużo bardziej zwarty. To bardziej jak oszczędzanie na drobiazgach: nie musisz pisać za każdym razem list. Może to być korzystne, jeśli nazwa zmiennej jest bardzo długa.

Ale jeśli trafisz na taki kod w czyimś projekcie, nie zdziw się 🙂


Komentarze
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION