Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Final field marked @NotNull is not initialized

I have this code:

public static class MyWebDriver extends RemoteWebDriver {
    @NotNull
    private final String nodeId;

    public MyRemoteWebDriver(@NotNull String nodeId) {
        super();
        this.nodeId = nodeId;
    }

    @Override
    public void quit() {
        System.out.println("deleting node: " + nodeId);
    }
}

and it's guaranteed that nodeId that is passed into constructor is not null. And because nodeId field is final I expect it to be initialised in my quit() method.

But, in super() constructor there is a try-catch block which in case of exception calls quit() method and throws an exception. And in this case nodeId that I get in my quit() method is not initialised (has null value).

Are there any ways of avoiding it except

@Override
public void quit() {
    if (nodeId != null) {
        System.out.println("deleting node: " + nodeId);
    }
}

this one? Which looks pretty stupid, because nodeId is marked as @NotNull.

like image 280
esin88 Avatar asked Mar 10 '17 13:03

esin88


1 Answers

But, in super() constructor there is a try-catch block which in case of exception calls quit()

This are two problems in one:

  1. constructors should not do any work except storing the given parameters in (final) member variables.

    [edit]

    Does that mean classes should not validate their inputs? I know many people who would disagree with having all of their objects possibly invalid instead of never existing at all. – chris

    By "should not do any work" I mean constructor should not calculate any property value from the parameters or call a dependency or a non public method to do the check.

  2. constructors should never call any other than private and/or final methods (within the class), either directly or indirectly (i.e. you mustn't call a final method which in turn invokes a non-final method).


The reason why you run into this problem is the violation of the single responsibility Pattern and Separation of Concerns.

What ever you do in the super classes constructor should most likely be done in a separate class and only the results of that process should be passed into your class (and its super class).

This obviously means that the quit() method also belongs to a different class.

like image 87
Timothy Truckle Avatar answered Oct 05 '22 13:10

Timothy Truckle