Jeg skal være den første til at indrømme, at der er ting, som kunne have været smartere i Java. Det skulle også være mærkeligt, hvis ikke der i løbet af godt 20 år er fundet på bedre måder at gøre ting på, og som bagudkompatibiliteten (som jeg sætter stor pris på) gør det svært at introducere. Alt taget i betragtning synes jeg dog, at antallet af egentlige smuttere er begrænset, og der bliver rettet op på dem - introduktionen af java.time til erstatning for java.util.Date og venner er et godt eksempel.
Nedenfor er en håndfuld eksempler på ting, som jeg synes er signifikant mere besværlige end nødvendigt. Folks forskellige baggrunde giver anledning til forskellige præferencer, og det er altid lærerigt at få et nærmere indblik i dem, så hvor synes I især, at skoen trykker?
Som jeg ser det kan manglerne ret beset inddeles i to overordnede kategorier. Den ene er konstruktioner, som også findes i andre sprog, men som fylder mere i Java - i vidt omfang det, mange benævner boilerplate-kode.
Det primære ankepunkt her er nok de basale (bean)klassekonstruktioner, altså settere og gettere, equals og hashCode. De generer mig som nævnt i et tidligere indlæg ikke så meget, fordi jeg ikke bruger meget tid på dem. Ja, de fylder i koden, men man kan i vidt omfang se bort fra dem, og bliver autogenereret af IDE'et. Det hænder endda, at de kan bruges til noget - gettere, som transformerer data, eller bare muligheden for at sætte breakpoints.
- Collection literals er derimod en mangel.
private static final Set<String> KEYS = ("foo", "bar", "baz");
At kunne erklære en immutable collection på samme måde som man fx kan erklære et array, altså som en konstant i koden uden at skulle konstruere, kalde .add eller .set og pakke ind i Collections.unmodifiable, vil være værdifuldt.
- Tupler mangler også.
public (int, double) compute() { ... return (x, y); } (int a, double b) = compute();
Det er ofte, at man har behov for at kunne returnere mere end en værdi fra en metode. Det kan sagtens laves med en Pair
- Defaultværdier for metodeparametre ville være fantastiske.
Det er især constructors, hvor defaultværdier ville give mening. Constructor chaining er fint nok, men så snart der kommer meget mere end to constructors i samme klasse taber man overblikket. Bare det faktum at det bliver meget langt med et hypotetisk kodeeksempel illustrerer fint pointen :-)
- Konstant (final) by default.
Bortset fra i løkker er det reglen snarere end undtagelsen, at variable er konstante. Det ville forhindre fejl og spare tid, hvis man eksplicit skulle erklære dem som ikke-konstante.
Den anden kategori er ting, som det aktuelt ikke umiddelbart kan lade sig gøre at lave i Java, for eksempel
- Algebraiske typer.
Algebraiske typer er en af de ting, som fik mig til at tænke "okay, det er smart" dengang jeg i en fjern fortid første gang stiftede bekendtskab med ML (*). Andre folks entusiasme for dem taget i betragtning lyder det måske som en dårlig undskyldning, men smart som det er, så sidder jeg bare sjældent og savner dem. Det skyldes måske, at de fleste datastrukturer, som min kode håndterer, er uniforme collections af instanser af samme klasse, så pattern matching på typerne ikke giver så megen værdi.
Man kan i mange tilfælde lave en billig udgave i Java ved at definere felter og metoder i en enum, og hvis det går helt galt er der den verbose løsning med en subclass pr. element i typen.
- By value.
Flaskehals nummer et i moderne computere er hukommelsen, så hvis man kan undgå at skulle følge en pointer er det en god ting. Der er derfor i nogen tilfælde signifikant overhead forbundet med at alting (bortset fra værdier af primitive typer) tilgås gennem referencer - det er igen ikke noget, som giver mig søvnløse nætter, men i HPC-agtige applikationer er det centralt. JEP 169 arbejder i øvrigt på at få det ind i Java, så der er lys forude.
(*): Jeg burde være fan af et programmeringssprog, hvis navn er mine initialer. Eller omvendt.
