Java 14 – Więcej informacji przy NullPointerException

Java w wersji 14 daje możliwość uruchomienia rozszerzonych informacji o znanym i lubianym NullPointerException.

Standardowo, gdy odpalimy taki kawałek kodu:

    public static void main(String[] args) {
        howLong(null);
    }
    
    private static int howLong(String s) {
        return s.length();
    }

Dostaniemy taki oto wyjątek:

Exception in thread "main" java.lang.NullPointerException
	at NPEEx.howLong(NPEEx.java:12)
	at NPEEx.main(NPEEx.java:5)

Natomiast, gdy uruchomimy naszą aplikację z dodatkowym argumentem dla Virtual Machine

-XX:+ShowCodeDetailsInExceptionMessages

Dostaniemy już nieco więcej informacji

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "String.length()" because "s" is null
	at NPEEx.howLong(NPEEx.java:8)
	at NPEEx.main(NPEEx.java:4)

I o ile w powyższym, prymitywnym przykładzie to nie potrzebujemy pomocy to, gdy mamy do czynienia z typowym anty-patternem “train wreck”:

person.getContactInfo().getAddress().getStreet()

To już dobrze wiedzieć co konkretnie się popsuło. Wówczas dostaniemy taką informację:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Address.getStreet()" because the return value of "ContactInfo.getAddress()" is null
	at NPEEx.main(NPEEx.java:5)

W IntelliJ możemy dodać argument do wirtualnej maszyny w menu Run -> Edit Configurations -> VM Options.

By być na bieżąco i mieć realny wpływ na tematykę tworzonych przeze mnie artykułów zapraszam do dołączenia do mojego newslettera.

Java 14 – ulepszona instrukcja switch

W Javie 14 ulepszono nieco składnie dla instrukcji warunkowej switch. Do tej pory przykładowa instrukcja wyglądała tak:

        String command = "add";
        String result = "";

        switch(command) {
            case "add":
                result = "ok";
                break;
            case "remove":
            case "update":
                result = "not ok";
                break;
            default:
                result = "meh";
                break;
        }

Dzięki użyciu nowej składni możemy powyższe zamienić na coś o wiele przyjemniejszego dla oka:

String command = "add";
String result = "";

switch(command) {
    case "add" -> result = "ok";
    case "remove", "update" -> result = "not ok";
    default -> result = "meh";
}

System.out.println(result);

Przede wszystkim pozbywamy się nieszczęsnego break, o którym to każdemu programiście zdarzyło się co najmniej raz w karierze zapomnieć. Dodatkowo wszystkie wartości jakie mają mieć taką samą obsługę wrzucam do jednego case’a, a nie tworzymy jeden pod drugim, co też jest generalnie czytelniejsze.

Ale to nie wszystko! Możemy też używać teraz switcha jako swoistej funkcji, mianowicie taki kod zadziała:

String command = "add";
String result = switch(command) {
    case "add" -> "ok";
    case "remove", "update" -> "not ok";
    default -> "meh";
};

System.out.println(result);

Możemy ominąć niepotrzebne przypisywanie, tylko użyć switch jako funkcji, z tą różnicą, że nawet nie musimy używać return (podobnie jak w lambdach jednolinijkowych).

By być na bieżąco i mieć realny wpływ na tematykę tworzonych przeze mnie artykułów zapraszam do dołączenia do mojego newslettera.