New in Java: Statements before super(…)

java statements before super(). Illustration of a man holding a huge cup of coffee that is the size of his torso.

As I mentioned in last week’s tip, one of the best places to keep current of any enhancements to the Java language and JDK is the JDK Enhancement Proposal website. It details the long-term roadmap for JDK releases including language enhancements and related technologies.

The topic for this tip is JEP447: Statements before super(...). This is a relatively simple language enhancement. It is a preview feature in Java SE 22.

Constructor Limitations

When we write a constructor in Java, we can explicitly call a superclass constructor within the constructor using the super(...) call, but it must be the very first line in our constructor.

In the same way, we can explicitly call a constructor within our own class from another constructor in the same class using the this(...) call. Again, it must be the very first executable line in that constructor.

public class Employee extends Person {

    private double salary;

    public Employee(double salary) {
        super();
        this.salary = salary;
        // other statements
    }

    public Employee() {
        this(0.0);
        // other statements
    }
    // other code 

} // end of class

We’re used to coding in this way, and in many scenarios it works just fine. But what happens if we want to validate a parameter before actually calling the superclass constructor?

public class Programmer extends Employee {

    public Programmer(double salary) {
        super(salary);
        if (salary < 0.0)
            throw new IllegalArgumentException("Negative salary!");
    }

    // other code 

} // end of class

We can validate the parameter after we’ve called the superclass constructor, but this means that we will potentially have done unnecessary work, i.e. run the superclass constructor and immediately throw an exception.

Solution 1: Using A Static Method

We’d obviously want a fail-fast constructor that validates the arguments before calling the superclass constructor. Currently we can only solve this problem by coding an additional static method:

public class Programmer extends Employee {

    public Programmer(double salary) {
        super(checkNegativeSalary(salary));
    }

    private static double checkNegativeSalary(double salary) {
        if (salary < 0.0)
            throw new IllegalArgumentException("Negative salary!");
        return salary;
    }

    // other code 

} // end of class

Solution 2: Statements Before super()

Unfortunately, the previous code isn’t very readable. Ideally what we’d like to do is to write the validation code directly in the constructor before calling the superclass constructor:

public class Programmer extends Employee {

    public Programmer(double salary) {
        if (salary < 0.0)
            throw new IllegalArgumentException("Negative salary!");
        super(salary);
    }

    // other code 

} // end of class

This makes our constructor code a lot more obvious, easy to read and more maintainable. This is the aim of JEP 447.

Restrictions

Obviously we can’t write any code that refers to the this instance before calling super(). This includes accessing any of the object’s fields, invoking any instance methods or using the this instance in any way.

We also can’t write code that refers to the super instance’s fields or instance methods before actually calling super().

We can also run into problems when referring to instances of inner classes and anonymous classes.

Further Reading and Signing Off

For a deeper dive into the additional issues around writing statements before calling super(), see the motivation and description sections of JEP 447.

Was this interesting? Please share your comments, and as always, stay safe and keep learning!

Leave a Comment

Your email address will not be published. Required fields are marked *

Thank You

We're Excited!

Thank you for completing the form. We're excited that you have chosen to contact us about training. We will process the information as soon as we can, and we will do our best to contact you within 1 working day. (Please note that our offices are closed over weekends and public holidays.)

Don't Worry

Our privacy policy ensures your data is safe: Incus Data does not sell or otherwise distribute email addresses. We will not divulge your personal information to anyone unless specifically authorised by you.

If you need any further information, please contact us on tel: (27) 12-666-2020 or email info@incusdata.com

How can we help you?

Let us contact you about your training requirements. Just fill in a few details, and we’ll get right back to you.