Is it a good idea to use the "final" modifier with getters and setters?

I was wondering why the last modifier is not used with getters and setters?

Why is this:

private int x;

public void setX(int x) 
{ 
  if(x >= 1) throw new IllegalArgumentException("X must be lower than 1");
  this.x = x; 
}

      

Instead of this:

private int x;

public final void setX(int x) 
{ 
  if(x >= 1) throw new IllegalArgumentException("X must be lower than 1");
  this.x = x; 
}

      

Doesn't improve encapsulation? I tried to clarify this with google, but I had no luck.

Thanks in advance.

+3


source to share


4 answers


One of the reasons you might want to leave the irregular setter behind is to allow subclasses to do their own, stricter argument checks:

public class Subclass extends Superclass {
    public void setX(int x) { 
        if(x >= 0) throw new IllegalArgumentException("X must be negative");
        super.setX(x); 
    }
}

      



Of course this violates the Liskov Substitution Principle because the subclass reinforces the precondition in the subtype.

+9


source


The purpose of the latter method in Java is that it cannot be overridden or hidden by subclasses. Hence, if you need this functionality for your getters / setters, it's perfectly fine to make them final, otherwise there is no purpose for that.



+1


source


I would strictly avoid setters when another reliable possibility might arise:

You might want to provide a setter in case you want to change a field.

You mentioned:

What if the developer violates the validation rules I provided, overriding the setter ... Should we go with the final keyword?

I would say: "Deny him this . "

Indeed, declaring a setter is like telling the world,
"You can provide me with some kind of field value, and then you can do your thing with me!" => procedural code

"Say! Don't ask . " Philosophy will say:
"Client, tell me what to do, I will do it."
And in general, your main "complex" logic will be in the main public api of the POJO.

I doubt the developer would be tempted to override the complete POJO logic without risking complete unfortunate behavior.

So, for example, instead of declaring a public setter for any value, force the value to be passed to the main method so you can control the flow:

public void computeWith(int x) {
  if(x <= 0) throw new IllegalArgumentException("X must be superior to 0");
  //code computing here.
}

      

You will notice that some fields may not even be needed in the POJO this way.

To summarize, it's easy to override a bad validation rule ... but dangerous for behavior.

Just my 2 cents.

0


source


There are arguments both ways, but if you make final methods (of any kind, not just getters or setters) somewhere down, another developer will curse you. It is very difficult to predict how your class will be used in the future and will restrict it by making it final, it usually becomes more difficult for a future developer.

For example, some poor soul needs to integrate your code with a new application that the company just bought. It's 3pm Friday afternoon and the demonstration will take place on Monday morning. If they could override the getter, they could force it to return the wrapped object from the new application, and everything would work. If this getter is final it should start changing, testing can free up your code to work over the weekend.

So have some empathy for future developers and don't make methods final unless you're really sure. Even then, I would not have worried.

Another use specifically for non-final getters is testing. It can be very convenient, especially during integration tests with less perfect code, to override the getter to inject a test instance of the class.

-1


source







All Articles