1

I would like to discuss a question about best practices regarding exception handling (e.g. in Java). Normally, when setting the attributes of a class, I check the arguments in the setters for validity, and if the arguments are not valid, I throw an IllegalArgumentException.

Besides the setters, sometimes also the constructor of the class allows to set some values for the attributes. So I also have to check the arguments in the constructor for validity. This, however, would lead to duplicate code. I can only think of one solution for this problem: Instead of directly setting the value of the attribute in the constructor, I call the setter, which then also validates the given value.

However, as the setters are public, this has the problem that I would call an overrideable method from within the constructor, which is bad. To solve this problem again, I could make the setters final, but this I have never seen.

Another possibility I could think of, theoretically, is to have a private or many private methods which check the arguments for validity and which are called by both the constructors and setters. But this would lead to even more code. What do you think are the best practices for this problem?

2 Answers 2

4

Great question, your hunch that you shouldn't set the setter methods as final or private is correct. You should allow child classes to override these as necessary.

Best practice is to call the setter methods in the constructor.

If other classes extend the class and override the setter methods with their own validations, the parent constructor will call the child's setter methods as long as the object is instantiated as the child class.

6
  • 1
    Can you give a non-smelling example where overriding a setter would be useful?
    – 5gon12eder
    Commented Jan 8, 2016 at 0:35
  • You give great points in your answer. I'm going to go back on my answer and agree with you, setters should have a simple role: assign the variable. Extending setters does smell a little funny, the real answer would depend on the team and the application's current practices (I know its a cop out). I've always been in favor of descriptive, simple method signatures (I.e. call a validate method inside of the setter and override it). But I can also see the case if you're trying to get the most out of every cycle and limit method calls and include the validation in the setter method. Whatever the ch
    – mikeo
    Commented Jan 8, 2016 at 0:45
  • (Continuation) Whatever the choice, make sure you're consistent throughout the system to make it easier to maintain.**
    – mikeo
    Commented Jan 8, 2016 at 0:46
  • @5gon12eder An example isJComponent.setEnabled(), which overrides Component.setEnabled() link. Besides of that, I also can not think of a trivial example which requires overridng a setter. But this is maybe because there is no trivial example, and some more sophisticated situations really demand overriding the setter. Furthermore experience tells, that one should not exclude something, even it does not seem likely.
    – Rolch2015
    Commented Jan 8, 2016 at 16:42
  • @5gon12eder Furthermore there might be some very simple reasons. For example, when I do not have access to the parent class and need to add some functionality to the setter.
    – Rolch2015
    Commented Jan 8, 2016 at 16:45
1

To solve this problem again, I could make the setters final, but this I have never seen.

I think that this is the appropriate solution.

I regret that you've never seen that before because I think that setters almost always should be declared final. Can you think of a good reason to override a setter in a derived class? What's the purpose of a setter? It assigns a value to a (hopefully private) attribute, possibly after verifying the new value. What useful could it be to override this? I cannot think of any situation where overriding the setter would be anything else but very poor code. So, yes, go ahead, make them final.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.