Totalt nærmer det seg 25 år siden jeg startet i min først jobb som utvikler. Jeg ble tidlig penset over i Java-sporet og de første 16-17 årene var dette hovedspråket på alle prosjektene jeg jobbet på. De siste 8 årene har jeg programmert mest i andre språk - Python, Ruby, Clojure, Scala, Groovy, ClojureScript, JavaScript og Typescript nevnes på CVen. Det har på en måte alltid vært Java i nærheten - for eksempel bak APIer som jeg har benyttet - eller at språket mitt kjører på JVM. Så litt kontakt har jeg hatt med min gamle sertifiserte følgesvenn.

Sertifiseringsbevis

Sist jeg programmerte Java var det version 8 som gjaldt. Så jeg tenkte rett og slett å gå gjennom alle versjonene etter det og se hva som er nytt. Hvordan har Java som språk og platform utviklet seg de siste årene? Kan Java fortsatt være et språk for nye prosjekter i dag eller er det bare andre JVM-språk som Kotlin eller Clojure som gjelder?

Moduler

I Java 9 fikk man endelig et skikkelig modul-system som jeg husker det hadde vært snakket om lenge. Det gir en mye bedre måte å pakke sammen Java-kode på og skal bidra til å løse JAR hell som de fleste sikkert har kost seg med.. Lurer på om dette er i bruk over alt nå?

JShell REPL

Også er det jammen en REPL - JShell, også fra Java 9. Dette har jeg ofte brukt å starte scala for å gjøre i Java-prosjekter - for eksempel å sjekke hvordan parseInt funker. Nå kan jeg altså bruke JShell - skikkelig tøft:

Test av JShell

Mener å ha hørt at JShell ikke er like bra som REPL i Clojure - men det skal vel noe til? Tipper det funker bra for å teste en del ting uten å skrive masse kode. Samtidig er det jo mange alternativer her - så dette er vel ikke akkurat killer-featuren jeg har savnet.

Garbage collection

På garbage collection fronten har det skjedd masse. Nesten hver eneste Java version nevner en eller annen forbedring eller tilskudd til GC systemet. G1 har blitt standard, og er oppdatert med full parallell støtte og diverse andre forbedringer. Det er kommet en ny garbage collector for low-latency systemer, ZGC, som ser veldig spennende ut! Vi har til og med fått en No-Op GC som ikke frigjør noenting - superrask om man allokerer en fast mengde greier som aldri skal frigis. Nå er jo ikke GC akkurat en del av Java-språket - men en oppdatert JVM har tydeligvis betydelige forbedringer her.

Jeg har tidligere skrevet en liten sak om å sammenligne forskjellige GC innstillinger. Kunne vært gøy å tatt opp tråden igjen her å gjøre litt sammenligninger av dagens alternativer.

Type inference

Man har heldigvis fått litt type inference - det var alltid pes med Java at man hadde stor grad av gjentagelse. I Java 7 eller noe sånt fikk man diamond operator - som gav type inference på generics. Nå har vi var keyword og enda litt bedre støtte:

// gamle dager
List<String> java5List = new ArrayList<String>();
// diamond operator - generics inference
List<String> java7List = new ArrayList<>();
// type inference med var keyword
var java10List = new ArrayList<String>();
var java10List2 = List.of("eple", "pære");
// skulle ønske det var sånn..
var javaWishList = ["eple", "pære"];

Skikkelig switch statement og pattern matching

Man kan kalle switch og få en verdi tilbake. Og med ny fancy pil-syntaks kan man også legge flere case alternativer sammen:

int day = (int) Math.round(Math.random() * 10) % 7;

boolean weekday = switch(day) {
   case MONDAY, TUESDAY, WEDNESDAY, THURSDAY -> true;
   case FRIDAY, SATURDAY, SUNDAY -> false;
   default -> throw new IllegalStateException("Unexpected day: " + day);
};

Med de siste oppdateringene har vi til og med fått litt pattern matching inn i switch. Dette skrev Odin et fint innlegg om før jul. Man kan sjekke både typer, null og records direkte 🥳

Pattern matching kom først ifm. instanceof operatoren - små skritt som gjør verden bittelitt bedre for Java-utviklere:

// old style med cast til string
if (obj instanceof String) {
   String s = (String) obj;
   System.out.println(s.length());
}
// med pattern matching
if (obj instanceof String s) {
   System.out.println(s.length());
}

Records - tuples i Java?

Støtten for records har kommet snikende i mange oppdateringer av Java. Anbefaler igjen Odin sitt innlegg fra desember for en flott gjennomgang, og brukbarhetsanalyse, av dette.

Jeg liker tanken på å slippe dustete klasser med get/set metoder og alskens tullball. Og jeg liker ikke tanken på å bruke Project Lombok eller lignende for å bøte på problemet. I min drømmeverden lagres egentlig det meste av data i lister og maps, men kanskje records er puslespillbiten som får meg til å endre mening?

record Point(int x, int y) {}

Point p = new Point(5, 7);

// toString er inkludert i pakken!
System.out.println("ma point: " + p);

Sealed classes

Sealed classes er en annen feature lagt inn i språket som lar deg begrense hvem som kan extende eller implementere klasser og interfacer:

public abstract sealed class Shape
   permits Circle, Rectangle, Square {...}

Disse bidrar sammen med records til å implementere støtte for sum types i Java. Det er en viktig forutsetning for å kunne implementere skikkelig pattern matching som nevnt lengre opp.

Unnamed classes

Dette er fortsatt preview funksjonalitet, men man kan altså nå lage en fil med minimalt av boilerplate for å kjøre et Java-program:

void main() {
   System.out.println("Crazy futuristic feature!");
}

String templates (er) var på vei!

Nok en preview feature er string templates. Man kan lage string uttrykk uten å bruke StringBuilder eller plusse sammen string objekter. Det tror jeg kan bli veldig nyttig:

String name = "Eivind";
String info = STR."My name is \{name}";

Man får også støtte for multiline string uttrykk (en annen ny feature fra Java 15) - og mer avansert formattering:

import static java.util.FormatProcessor.FMT;

void main() {
   String name = "Eivind";
   double age = 47.43453;

   String info = FMT."""
      Name: \{name}
      Age:  %2.1f\{age}""";

   System.out.println(info);
}

// output:

// Name: Eivind
// Age:  47.4

Min kollega Robin gjorde meg oppmerksom på at string templates er trukket fra versjon 23 i nåværende form. Blir spennende å se om det dukker opp igjen da. Jeg synes det er en nyttig feature, men kunne kanskje tenkt meg en noe annen tilnærming forhold til syntaks. Og det er vel nettopp grunnen til at det trekkes så vidt jeg skjønner..

Concurrency updates og virtual threads

Her skjer det mye spennende nå. Lettvekts tråder er noe man har trengt biblioteker for lenge i Java og er en viktig byggekloss når man skal lage raske systemer med stor grad av samtidighet. For å gjenta litt mer av hva Odin sier - dette fortjener en egen post 😇

Oppsummert!

Jeg har et inntrykk av at det skjer en god del spennende ting på Java-fronten. Litt bevegelser på selve språket og mye rart på selve plattformen. Har lyst til å ta en grundigere titt på både GC og virtual threads - stay tuned så kanskje det kommer en oppdatering her å bloggen vår etter hvert.

Om noen har bruk for en sertifisert (og nå litt mindre utdatert) Java-utvikler er jeg ledig for nye oppdrag. Ta kontakt om du har noe du trenger hjelp til!