1. Syntaktisk socker

Programmerare älskar när komplex kod eller logik kan skrivas på ett par rader, vilket gör koden kompakt och läsbar. Och skaparna av programmeringsspråk hjälper ibland till med detta.

En smart språkfunktion som låter dig ta en genväg (skriva mindre kod) kallas syntaktisk socker . Men för att vara ärlig så finns det väldigt lite av det i Java.

Javas skapare gjorde allt de kunde för att eliminera all redundans i Java. Om C++ låter dig göra något på 20 sätt, låter Java dig göra det bara på ett sätt.

Men varken Java-programmerare eller Javas skapare gillade bristen på frihet. Och ibland gör socker livet lättare för vanliga människor som du och jag.

Förresten, du har redan stött på lite syntaktisk socker: autoboxning och unboxing . Låt oss jämföra:

Lång kod Kompakt 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)
{
   ...
}

Istället för den långa koden som till vänster kan du skriva den mer kompakta koden till höger. Och intelligent Java-kompilator kommer att generera den utförliga versionen av koden baserat på den korta versionen av koden. Det är precis vad syntaktisk socker är.


2. Slutledning av en variabels typ: varnyckelordet

I Java 11 blev kompilatorn ännu smartare och kan nu bestämma typen av en deklarerad variabel baserat på typen av värde som tilldelats den . I koden ser det ut så här:

var name = value;

Var nameär namnet på en ny variabel, värde är dess initiala värde och varär ett nyckelord som används för att deklarera variabeln. Typen av namnvariabeln kommer att vara densamma som typen av värdet som tilldelats den.

Exempel:

Hur vi ser koden Vad kompilatorn ser
var i = 1;
int i = 1;
var s = "Hello";
String s = "Hello";
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};

Kompilatorn själv bestämmer, eller härleder, variabelns typ baserat på värdet som tilldelats den.

Programmerare diskuterade intensivt om de skulle lägga till en sådan funktion till språket. Många människor fruktade att det varskulle missbrukas och att kodläsbarheten skulle bli lidande som ett resultat.

Det finns ett korn av sanning i detta, så det är bäst att använda vardär det ökar kodens läsbarhet. Till exempel dessa i två fall:

Fall 1: Om man tittar på värdet som tilldelats variabeln är variabelns typ omedelbart tydlig

Koda Förklaring
var stream = url.getInputStream();
Variabeln är anInputStream
var name = person.getFullName();
Variabeln är aString

I dessa fall bör du inte använda var. Tja, vad är variabelns typ?

Koda Förklaring
var result = task.execute();
Det är svårt att avgöra variabelns typ
var status = person.getStatus();
Det är svårt att avgöra variabelns typ

Fall 2: Variabelns typ är inte viktig för att förstå koden

Kod har ofta inget behov av att anropa metoder på en variabel, t.ex. när en variabel helt enkelt används för att tillfälligt lagra något. I det här fallet varminskar användningen definitivt inte läsbarheten för koden:

Lång kod Kompakt kod
var data = stream.getMetaData();
storage.save(data)
Vi fick metadata från streamströmmen och sparade den i storageförvaret. Variabelns dataspecifika typ är inte viktig.

Den gyllene medelvägen

Nu ska jag ge tre sätt att skriva samma kod. Att använda varskulle vara det bästa alternativet.

Koda Notera
dest.writeHeaderInfo(src.getFileMetaInfo());
För kompakt
var headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
Precis rätt
FileMetaInfo headerInfo = src.getFileMetaInfo();
dest.writeHeaderInfo(headerInfo);
För detaljerad

När vi flyttade från versionen med 1 rad till versionen på 2 rader gjorde vi koden lite mer läsbar genom att använda ett variabelnamn ( ) headerInfo. Nu är det klart att metoden inte bara returnerar metainformation, utan rubrikinformation.

Den tredje versionen är alltför utförlig. Att det headerInfoär a FileMetaInfoframgår redan av getFileMetaInfo()metoden. Syftet med metainformationen är mycket mer intressant.



3. Utelämna typen med diamantoperatorn:<>

Redan innan varoperatören dök upp gjordes det försök att lära kompilatorn hur man härleder samlingstyper. Du håller med om att den här notationen ser lite överflödig ut:

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

Från och med den sjunde versionen av Java, när du skriver en samlingstyp, kan du utelämna typen av samlingselement om den angavs när du deklarerade en variabel. Med andra ord kan koden ovan skrivas i en något förkortad form:

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

Som du kan se behöver du inte längre skriva String en andra gång. Inte lika coolt som med var-operatören, men det verkade som framsteg på den tiden.

De tomma vinkelfästena i samlingstypen kallades diamantoperatorn , eftersom de två vinkelfästena vagt liknar en diamant.

Det är inte önskvärt att använda varnyckelordet och diamantoperatorn samtidigt :

var list = new ArrayList<>();

Det finns ingen information alls om typen av element som lagras i samlingen, och samlingstypen kommer att vara ArrayList < Objekt >.



4. Dubbla lockiga hängslen

Kommer du ihåg snabb arrayinitiering?

Vi har precis listat värden i lockiga hängslen, så här:

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

Javas skapare älskade idén att använda lockiga hängslen för att förenkla skrivelementen i en array. Men hur är det med samlingar?

Javas skapare hade tillräckligt med kreativt tänkande för samlingar också, så att de kunde använda ett trick med dubbla lockiga hängslen.

Med socker Utan socker
var list = new ArrayList<String>()
{{
   add("Hello");
   add("How's");
   add("Life?");
}};
var list = new ArrayList<String>();

list.add("Hello");
list.add("How's");
list.add("Life?");

Om kompilatorn stöter på kod som i exemplet till vänster, konverterar den den till koden till höger.

Koden blir inte mycket mer kompakt. Besparingarna här är ganska obetydliga: du behöver inte skriva listvarje gång. Detta kan vara användbart om variabelnamnet är mycket långt.

Men om du stöter på sådan kod i ett projekt, bli inte förvånad 🙂