brace yourselves java 17 is coming (3/6)

hands on: java 14


in the last episode, we got in touch with java 13 and text blocks. in java 14, there are two really interesting and refreshing features. we're talking about the more chatty null pointer exceptions and records. let's start.


null pointer exception message

with java 14 null pointer exceptions are more talky when it comes to an error. before we learn the new feature, let's consider the following expression:

levelOne.doSomething())

it's obvious where the null pointer exception may occur. the service might now have been initialized and a null pointer exception will be thrown. but when there are more method executions inlined, it's hard to tell, which instance might have thrown the error.

levelTwo.doSomething().doSomething())

thanks to java 14, null pointer exceptions now have a message. in former releases, null pointers never had a message. so lets see how the message looks now with this new feature. the message looks like that for levelOne instance:

java.lang.NullPointerException: Cannot invoke "kmo.java14.NullPointerExceptionExample$LevelOne.doSomething()" because "levelOne" is null

for the levelTwo instance, the message looks like that:

java.lang.NullPointerException: Cannot invoke "kmo.java14.NullPointerExceptionExample$LevelTwo.doSomething()" because the return value of "kmo.java14.NullPointerExceptionExample$LevelOne.doSomething()" is null

both messages look very useful, neat! to be honest everything looks better than a null message.


this new mechanism supports us not only when calling methods, it's also allowed with fields, constants, parameters and lambdas. this is even possible when doing inline calculations, the result of the calculation:

final Integer one = 1;
final Integer two = 2;
final Integer three = null;

final var result = one + two + three;

will be this:

java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "three" is null

records

record is a new keyword introduced with java 14. this keyword can be applied at class level in replacement of the class keyword. it describes the class as immutable and comes with a new syntax. an example of a class declaration with a constructor of mandatory parameters can be like this:

record Car(String model, String vin) {
}

if we want to have an optional parameter, the notation is like that:

record Car(String model, String vin, String name) {
    public Car(String model, String vin) {
        this(model, vin, null);
    }
}

but wait there is more. this keyword doesn't it make it immutable only, it generates us a lot of code. so if we want to write the same code, not using the new keyword record, the code will look the following:

final class Car{

    private final String model;
    private final String vin;

    public Car(final String model, final String vin) {
        this.model = model;
        this.vin = vin;
    }

    public String model() {
        return model;
    }

    public String vin() {
        return vin;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        final Car car= (Car) o;
        return Objects.equals(model, car.model) && Objects.equals(vin, car.vin);
    }

    @Override
    public int hashCode() {
        return Objects.hash(model, vin);
    }

    @Override
    public String toString() {
        return "Car{" +
                "model='" + model + '\'' +
                ", vin='" + vin + '\'' +
                '}';
    }

well if this isn't a load of code we saved writing.


summary

one might say:

meh, only 2 features released in java 14.

yes, that's true, but those features have a very high value. for analytics reason, the more chatty null pointer exception is very helpful. it will save you time by not having to debug the code to see where the exception really occurs. the records save us also a lot of time writing all the code. not written code, is the best code. we do less mistakes and don't have to use libraries like lombok. i just wonder what took oracle so long to implement such features. those features should've been released much earlier in my option, but i'm more happy to see it is available now for everyone.


so what do you think about the changes? do you like it and will try to adapt them in upcoming process, or will you wait for the next lts before using it? let me know.


see the full source code here: https://github.com/kmo-dev/java14

Recent Posts

See All