Skal Java også tillade nøgleordet 'var'?

Mange andre sprog benytter nøgleordet 'var' til deklarering af variable uden at behøve at skrive, hvilken type der er tale om. Nu er 'var' på tale til Java.

Java er på ét bestemt punkt et af de store beslægtede programmeringssprog, der insisterer på at holde mest på formerne. I hvert fald når der skal deklareres variable. Men nu er et forslag på banen om, at Java skal bløde lidt op og lade udviklerne bruge nøgleordet 'var'.

Forslaget behandles nu blandt OpenJDK-bidragsyderne, så der er stadig lang vej, før det bliver muligt at bruge 'var' i Java-kode.

Argumentet for at inkludere 'var' er først og fremmest, at det vil gøre koden lettere at læse, når man ikke behøver at deklarere en variable ved at angive typen i deklarationen, når den kan udledes af sammenhængen. Det er især nyttigt til lokale variable.

Omvendt kan brugen af 'var' også betyde, at det kan være sværere at se, hvilken type man har med at gøre, hvis det ikke er indlysende ud fra deklarationen.

Hvis det kommer med i en fremtidig udgave af Java, så er det ikke sikkert, det ender med en 'var'-løsning. En meningsmåling lader Java-udviklere stemme på flere forskellige mulige implementeringer som eksempelvis 'var/let' eller 'auto'.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk

Kommentarer (18)

Torben Mogensen Blogger

Jo mere typesikker inferens man kan lave, jo bedre, så længe det er muligt for programmører i særlige tilfælde at skrive typerne eksplicit, dels som dokumentation og dels som sanity check. For lokale variable er der dog sjældent behov for at dokumentere typerne -- de fremgår i reglen ret tydeligt at initialisatorerne.

Jeg så allerhelst, at initialisering var påtvunget, men det er ikke bagudkompatibelt, så det bliver næppe til noget.

Jeg synes, at det er en god ide at skelne mellem konstanter og muterbare variable, så jeg har stemt på var/let, da jeg synes at var/val har for lidt visuel forskel.

Casper Pedersen

Java er type safe, og at skulle skrive "var stream = list.stream(); " giver jo ikke nogen mening da man allerede har '<type> <variable name>'.

Jeg kan ikke se i deres argumentation at 'var' vil gøre noget som helst bedre. Man skal allerede skrive meget i Java, og at tilføre mere give ikke meget mening. Se bare hvad der skete me C++ .....

Nikolaj Brinch Jørgensen
Jesper S. Møller

Java er type safe, og at skulle skrive "var stream = list.stream(); " giver jo ikke nogen mening da man allerede har '<type> <variable name>'.


Jeg tror du har misforstået, Casper, 'var' skal jo netop reducere hvor meget man skal taste. Man behøver ikke skrive:

Map<String,List<AccountInformation>> accounts = someService.getAccounts();
// Gøre noget med accounts.
// Gøre noget mere med accounts.

når oversætteren kan udlede typen, så man blot kan skrive:

var accounts = someService.getAccounts();
// Gøre noget med accounts.
// Gøre noget mere med accounts.

Hvis man nu skifter typer undervejs kan man også slippe for at skulle konsekvensrette nogle af de steder, man har brugt typen.

Lasse Lindgård

Type inferens er en meget velkommen feature i Java.

De bør dog kopiere Scala og tilføje både var og val. Forskellen på de to er at val er final - dvs. at den kun kan tildeles én gang.

Man kunne også være fræk og kun tilføje val - det kunne måske opdrage lidt på visse udviklere.

Martin Jünckow

Ærlig talt ville jeg ønske man ikke havde indført var support i C#.

Det er korrekt at der er visse tilfælde (især i forbindelse med LINQ) hvor var er et positivt tiltag.

Men det jeg oplever istedet er at folk nu koder C# som om det var Javascript og bruger var-supporten som undskyldning for ikke længere at erklære typer overhovedet - selv når vi taler simple strings or int variable.

Som konsulent oplever jeg dette mere og mere på store enterprise projekter hvor der simpelthen ikke har været god nok styring på en fælles kodestandard (hvilket desværre er mere reglen end undtagelsen rundt omkring).

Jeg ved godt at man gerne vil gøre Java sproget mere tilgængeligt, men jeg synes man skal tænke sig grundigt om før man indfører den her slags support i Java som man ellers hidtil har formået at holde rimelig clean og fri for popsmarte koncepter såsom var.

Philip Munksgaard

Jeg ved godt at man gerne vil gøre Java sproget mere tilgængeligt, men jeg synes man skal tænke sig grundigt om før man indfører den her slags support i Java som man ellers hidtil har formået at holde rimelig clean og fri for popsmarte koncepter såsom var.

Jeg har svært ved at se hvad der er popsmart ved typeinferens. Hindley-Milner stammer oprindeligt fra 1969 og har været brugt i ML og lignende sprog siden da.
Manglen på typeinferens har aldrig givet mening i statisk typede sprog som Java og C#.

Martin Jünckow

Type-inferens er ganske brugbart og det nyder jeg da også godt af i mange sammenhænge i C#.
Men der er en del mere til type-inferens end introduktionen af var keywordet.

Jeg synes det er generelt dårlig praksis ikke at erklære typer og det går ud over læsbarheden.
Imo er var oftest bare et symptom på dovenskab.

Johnnie Hougaard Nielsen

'var' skal jo netop reducere hvor meget man skal taste

Med et IDE (som Eclipse) kan jeg netop blot skrive

accounts = someService.getAccounts();

og derefter bede den om at lave det til en lokal variabel (det er nemt). Så får jeg jo den fulde definition i koden, men det ser jeg som en fordel for læsbarheden. Selv om det ikke er svært at få Eclipse til at vise returtypen, er der nu en behagelighed ved den helt umiddelbare synlighed.

Generelt synes jeg ikke at fokus på "forbedringer" skal være at gøre selve source koden en smule kortere, på bekostning af den umiddelbare forståelighed. Men ok, jeg er også blandt dem som foretrækker statiske typer og typestærke sprog, også for ikke at skulle vente til test med at fange alt for banale fejl.

Kenneth Ellested

For år siden havde jeg svært ved at vende mig til at bruge var, men i dag syntes jeg det er både bekvemt og smukt, og jeg vil ikke bytte tilbage. Det giver ikke nogen umiddelbare fordele at erklære sine typer "igen", og compileren skal nok fange det der ikke kan lade sig gøre. Som andre har nævnt giver var mindre støj i koden, og kan gøre det nemmere at refaktorere. Så der er stadigvæk god sikkerhed, bare med lidt mindre støj.
Btw. så er det meste syntactic sugar blot en vanesag, ligesom det er at skifte til et andet sprog.

Min Wu

Det fungerer jo fint på Swift med let/var, uden at miste type safety. Compiler og debugger check hele tid man har bruge det rigtig.

Det kan være en problem, hvis man kommer fra javascript, og skriver code i simple editor uden nogen IDE check.

Henrik K. Jensen

Jeg ser ikke den store ide i at indføre det, men heller ikke det store problem. Den tid det tager at skrive den korrekte type erklæring er meget lille i forhold til den tid det tager før koden er (nogenlunde) fejlfri, så for mig ligner det mest en måde at gøre syntaksen mere kompliceret på.
Eksempler som:
var list = new ArrayList<String>();
Syntes jeg ikke er gode, min erklæring ville nok have været:
List<String> list=new ArrayList<String>();
I praksis er forskellen nærmest ubetydelig, men den sikre dog at jeg ikke bruge metoder som er begrænset til ArrayList (I de fleste tilfælde er det uden betydning).

Min holding til sådanne "optimeringer" af syntaksen er ikke specielt positive, men næsten neutrale.

Johnnie Hougaard Nielsen

Jeg ser ikke den store ide i at indføre det

Jeg tror at en bagliggende hensigt er at gøre Java mindre "skræmmende" for nogen som er lært op med Javascript eller andre sprog der lader mange flere ting være implicitte, sammenlignet med det ret eksplicitte Java. Især generics kan give nogle ret lange typer, fx når en collection gemmes i en anden.

Med lidt syntaktisk sukker kan dit eksempel forresten forkortes til:
List<String> list=new ArrayList<>();
Her er der en meget sikker type-inferens på den helt korte bane.

Enig med pointen i at det ofte er mere rent at have resultatet som en mere abstrakt type, end hvad det konkrete objekt er skabt med. Det gør det også lettere hurtigt at se om der er ben i at skifte til en anden implementering.

Niels Dybdahl

Med closures i Java 8 er der allerede kommet meget mere typeinferens i Java, så indførelsen af var vil være et lille skridt i sammenligning. I begge tilfælde er det godt at IDEen kan vise typen på en variabel.

Martin Møller

Jeg programmerer til dagligt i C# og jeg må indrømme, at jeg stadig ikke er faldet til med "var" selv om flertallet er glad for at bruge det. Jeg synes, det er forstyrrende, at man nogle gange kan se typen i begyndelsen af en linje, nogle gange skal tænke sig frem til den ved at afkode linjen, mens man i andre tilfælde ikke har en chance for at se, hvilken type man får fat på. For eksempel:

var content = CollectionOfStuff.GetNext();

For mig gør det ikke koden mere læsevenlig, som ellers er det argument jeg hører oftest. Specielt ikke, hvis man laver code review i et andet værktøj end IDEen, som ikke hjælper med at afkode typer automatisk. Vi skriver også const, readonly, etc. for at vise andre programmører, hvordan vi havde tænkt os at en variabel skal bruges og opføre sig, og for at få oversætteren til at hjælpe med at håndhæve det. Jeg opfatter typeerklæringer på samme måde (selv om det selvfølgelig nogle gange kan være trivielt). Det er rigtigt, at det kan fylde meget, hvis man skal erklære og initialisere en variablen med et langt navn, men i det tilfælde, ville jeg foretrække, hvis man i stedet kunne skrive noget i stil med:

StringBuilder errorMessage = new ("Something is wrong:");

Martin Jünckow

Rigtig god pointe med code review, her har jeg det på samme måde - især fordi vi anvender web-værktøjer hertil som jo ikke ligefrem har den intellisense support der i VS lader en hover over "var" for at se typen.

I det hele taget er jeg ikke meget for at man er afhængig af så avanceret IDE integration for at koden er læsbar, ens kode burde skrives så den kan læses lige godt i enhver standard tekst editor.

Michael Cederberg

Java er forfærdeligt verbose så egentligt burde jeg være glad for denne feature, men nej.

For mig gør det ikke koden mere læsevenlig, som ellers er det argument jeg hører oftest. Specielt ikke, hvis man laver code review i et andet værktøj end IDEen, som ikke hjælper med at afkode typer automatisk.

Jeg er også stor modstander af denne feature i C# kode. Det er fint nok når det fx er en assignment hvor det er åbenlyst hvad der sker:

var sb = new StringBuilder();  
sb.Append(”Hello”)

Det er også fint nok når typen bliver meget complex. Men i de fleste tilfælde bliver "var" blot en substitut for et simpelt klassenavn – måske med en type parameter – og der er det svært at se gevinsten.

Faktisk fungerer det fint med min egen kode. Men når jeg skal læse andres kode er gør de manglende typer det sværere. Det føles lidt som at læse kode i nogle af de dynamisk typede sprog (selvom C# i dette tilfælde er 100% statisk typet).

void f(SomeClassX x, SomeClass y)  
{  
    var r = x.Size;  
    foreach (var yItem in y.Items) {  
        r.Aggregate(yItem, (x,e) -> x.ConvertToBase(e));  
    }  
    x.Apply(r);  
}

(hvad sker der i ovenstående? :-) )

Jeg er stor fan a lambda funktioner i både Java og C#. Men det er også et sted hvor manglende typenavne i parameterlisten nemt kan gøre koden svær at læse. Af samme grund har jeg advokeret kraftige begrænsninger i brug af både var og lambda funktioner alle de steder jeg har arbejdet.

I stedet for introduktion af var, så jeg hellere at man lavede mulighed for type aliaser, både for en class og en metode (C++ har noget af denne feature). Noget i retning af:

class HashMap<K,V>  
{  
    type KeyValuePair<K,V> EntryPair;  
   
   . . .  
}

Hvis java skal låne fra C# og andre kunne man med fordel låne følgende:

  • Rigtige bruger definerede value typer
  • Generics der ikke bare er syntaktisk sugar
  • Constraints på generics
  • Properties (i stedet for settter/getter metoder)
Log ind eller opret en konto for at skrive kommentarer