aspose file tools*
The moose likes Beginning Java and the fly likes Best Practice for getters and setters Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Best Practice for getters and setters" Watch "Best Practice for getters and setters" New topic
Author

Best Practice for getters and setters

Dennis Korbar
Greenhorn

Joined: Jan 14, 2009
Posts: 20
Hello,

I got a question about getters and setters, I'm wondering for some time now, about the best approach of setting/getting private or protected fields in the class' code to which those fields belong. (in the constructor for example)
I used to go about this by just using the fields directly like this:

But lately I've been using the getters and setters inside of the class' code like this:


In the given example this won't make any difference. But I thought it might be better to use the getters and setters in case that there'll be some restrictions in setters or some modifications done in getters, so these modifications or restrictions (or whatever will be going on in the setters and getters ;)) will be centralized.
I would like to hear the opinion of you guys about this, how do you set or get values of variables inside of the class that you are currently developing, does my second approach make any sense? Is it good or bad practice?

Thanks in advance for your input!
Dennis
Steffen Schmitt
Greenhorn

Joined: May 08, 2008
Posts: 14
Hi!

In my opinion, you are right about possible restrictions. Maybe the best way to keep instance variables from doing what they shouldn't do is not to access them directly. Technically speaking you can do this from within an inner class (like you did in your first example). But it would be much more appropriate to access them via getter and setter methods, using them to check for and/or elimintae illegal values. Plus the safety enhancement of declaring your getter and setter methods to throw whatever exception they might throw at runtime ... and to keep solutions at hand how to react in case this should ever happen.

Hope this helps ...

Cheers,

Steffen


The man who sets out to carry a cat by its tail learns something that will always be useful and which never will grow dim or doubtful.
-- Mark Twain
Rusty Shackleford
Ranch Hand

Joined: Jan 03, 2006
Posts: 490
Calling the setters in the constructor is needless overhead. Method calls are relatively expensive. Any method calls in the constructor should be for things more complicated then just setting variables.

IMO, if the setter does nothing but set a variable without any other validation or computation just make the variable public. Maybe it is because I use python more than anything these days, which has no real concept of private members.


"Computer science is no more about computers than astronomy is about telescopes" - Edsger Dijkstra
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 31069
    
232

Rusty Shackleford wrote: Method calls are relatively expensive.

Compared to what? I've never encountered a situation where I've had to worry about method calls. If all the method does is a simple get/set, the compiler might optimize it away. Regardless, how much time could a method call possibly take? I worry seeing this in a beginner forum that it will teach people that methods are somehow bad.

Dennis: I think this more of a design preference. The static analysis tool I use frowns on calling public non-final setters from a constructor. The reason being that a subclass could change the behavior on you. This i agree with.


[Blog] [JavaRanch FAQ] [How To Ask Questions The Smart Way] [Book Promos]
Blogging on Certs: SCEA Part 1, Part 2 & 3, Core Spring 3, OCAJP, OCPJP beta, TOGAF part 1 and part 2
Dennis Korbar
Greenhorn

Joined: Jan 14, 2009
Posts: 20
Jeanne Boyarsky wrote:
Rusty Shackleford wrote: Method calls are relatively expensive.

Dennis: I think this more of a design preference. The static analysis tool I use frowns on calling public non-final setters from a constructor. The reason being that a subclass could change the behavior on you. This i agree with.


Yeah, that's probably a good point
Rusty Shackleford
Ranch Hand

Joined: Jan 03, 2006
Posts: 490
Jeanne Boyarsky wrote:
Rusty Shackleford wrote: Method calls are relatively expensive.

Compared to what? I've never encountered a situation where I've had to worry about method calls. If all the method does is a simple get/set, the compiler might optimize it away. Regardless, how much time could a method call possibly take? I worry seeing this in a beginner forum that it will teach people that methods are somehow bad.

Dennis: I think this more of a design preference. The static analysis tool I use frowns on calling public non-final setters from a constructor. The reason being that a subclass could change the behavior on you. This i agree with.


Compared to this.a=a.

Method calls are expensive, it should be obvious if you look at recursion for example. The reason it is so slow compared to simple iteration is because of the method calls.

That is not to say that method calls should be avoided, but making a method call to a one line method is a waste. On the flip side a 150 line method is probably overkill, and needs to be looked at hard.

This is appropriate for a beginner, as these sorts of thought processes are critical to really understand programming.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61766
    
  67

I'm not buying it. Any difference in performance between setters and direct assignment will be negligible. Basing an important design decision such as the use of encapsulation on this would be nothing short of folly -- a clear case of premature optimization.

Using recursion as an example of a performance issue is unconvincing -- simply death by a thousand paper cuts.


[Asking smart questions] [Bear's FrontMan] [About Bear] [Books by Bear]
Rusty Shackleford
Ranch Hand

Joined: Jan 03, 2006
Posts: 490
Bear Bibeault wrote:I'm not buying it. Any difference in performance between setters and direct assignment will be negligible. Basing an important design decision such as the use of encapsulation on this would be nothing short of folly -- a clear case of premature optimization.

Using recursion as an example of a performance issue is unconvincing -- simply death by a thousand paper cuts.


Method calls are expensive, there is no argument.

If the setter did something more than this.a=a(such as validation) then there would be a valid reason to call the mutator, and not all 1 line methods are a waste, but in this case it is pointless to do that. It is NOT premature optimization in this case because the method call costs considerably more than a simple assignment. It is intelligent programming. Again, put some validation or something else in the mutator and you are correct.

What if this class was instantiated 1000 times in a program? It would be the same death by 1000 paper cuts that recursion can bring. That 'negligible' difference is suddenly very large.

I am not saying recursion is always bad, try to move through a tree or write a towers of hanoi-like problem without recursion. It may not have been the best argument, but I was simply stunned to be asked why a method call is expensive from someone very knowledgeable.
Bear Bibeault
Author and ninkuma
Marshal

Joined: Jan 10, 2002
Posts: 61766
    
  67

Still not buying it. You'll have to put some significant numbers behind your argument. Violating precepts of encapsulation because of a phantom performance concern is the epitome of premature optimization. I find it difficult to believe you can prove that the use of setters will create a demonstrable and perceivable difference in performance.

There may be no arguing that a method call will be more "expensive" than an assignment, but to argue that design decisions should be made based upon such negligible differences is where I differ.

Moreover, setters are mandatory in many environments where the JavaBean pattern must be adhered to for things to work properly.

Denis Wen
Ranch Hand

Joined: Nov 11, 2008
Posts: 33
but what's about child class overwriting the implementation of the getter? Should the caveat be that only private mutators should be called in the constructor, wait... mutators are public by design... how than to go around this?
Bear Bibeault wrote:Still not buying it. You'll have to put some significant numbers behind your argument. Violating precepts of encapsulation because of a phantom performance concern is the epitome of premature optimization. I find it difficult to believe you can prove that the use of setters will create a demonstrable and perceivable difference in performance.

There may be no arguing that a method call will be more "expensive" than an assignment, but to argue that design decisions should be made based upon such negligible differences is where I differ.

Moreover, setters are mandatory in many environments where the JavaBean pattern must be adhered to for things to work properly.

Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40052
    
  28
The "correct" caveat is that methods called from the constructor should be "private" OR "final". That will sort out the problem about subclasses.
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3018
    
  10
Campbell Ritchie wrote:The "correct" caveat is that methods called from the constructor should be "private" OR "final". That will sort out the problem about subclasses.

Or static - that works too. The key point is that all three types of methods cannot be overridden.

Denis Wen wrote:mutators are public by design

Not necessarily. The most basic type of mutator is a public setter, but any method that can change instance data is a mutator - this can apply to private methods as well as package or protected methods.



Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40052
    
  28
Static to set an instance variable???
Mike Simmons
Ranch Hand

Joined: Mar 05, 2008
Posts: 3018
    
  10
Well, now you're addressing a more specific circumstance than either of us were in our previous quotes. But, yeah, sure. Why not?

Naturally, a plain vanilla setter can't be static. But classes can contain methods other than setters and getters, after all. A static method can be used to initialize an instance field in two ways, that I can think of:

Or:

The first one is a bit unusual, I think. I'm not sure if I've ever used it. But it's possible, at least. The second is something I do fairly often. I like to make fields final whenever possible, and this requires that they be unambiguously assigned in the constructor. But if initialization of a value requires some complex process, I will happily factor that out into another method, often static, that returns the value I need. To improve readability, if nothing else.

And actually, going back to the earlier question: this is my main reason not to use setters in a constructor, and instead use direct field assignment. Because if you declare a field final, the compiler requires that it be definitely assigned by the end of the constructor. And the rules for definite assignment do not require, or even allow, the compiler to go into each and every method that you might call from the constructor, to analyze whether the field has been initialized or not. That can become too much work, and hard for humans to read as well. Instead, the field must be set, unambiguously, within the constructor itself. (Or within the field's own initializer in its declaration, or in an instance initializer (seldom used in practice).) Initializing a final field with a setter is impossible - you just annoy the compiler.

So that is, I think, the primary reason why I reject the notion that you should always use getters and setters, rather than direct access. The performance argument is too weak for me to care about, at least 99% of the time. But allowing final fields to be initialized, clearly and unambiguously, is much more important to me.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 40052
    
  28
Yes, I take your point.

And I don't have a particular liking for plain get and set methods myself.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

I just wanted to play with some code to see how 'expensive' method calls actually are. So I wrote this:


I ran the tests a bunch of times, and some typical output:


When run with 10,000 assignments there is usually less than 100ns difference in times (and it flip-flops on which type of calls are faster - methods or direct assignment) - this suggests to me no difference between the two. When I ran it with 100,000 assignments there averages about 400ns difference in times (the method calls are typically longer than direct assignments). So with enough method calls, then perhaps a small difference can be measured but to program against this difference is a waste of thought processes.

The choice between using methods or not should be based on considerations other than speed.


Steve
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 31069
    
232

Rusty Shackleford wrote:Method calls are expensive, there is no argument. ... but I was simply stunned to be asked why a method call is expensive from someone very knowledgeable.

Sure there is. Bear and I disagree with you. If you have at least two experienced developers who disagree with a statement, you can't say it is a universal fact that should be accepted without argument.

Rusty Shackleford wrote:What if this class was instantiated 1000 times in a program?
I instantiated it over a million times - nothing.

Rusty Shackleford wrote:Method calls are expensive, it should be obvious if you look at recursion for example. The reason it is so slow compared to simple iteration is because of the method calls.

Assuming you are comparing the same algorithm. Some recursive algorithms do more work.

Rusty Shackleford wrote:This is appropriate for a beginner, as these sorts of thought processes are critical to really understand programming.

Sure. Assuming the beginner knows that it takes millions of calls to make even a 10 millisecond difference. (see benchmark below)

Using the below benchmark, it came back has 50-60 milliseconds with the setter option or the direct assignment. And I ran it 2.5 million times. I find it hard to believe Dennis is making millions of calls in his code. (And I still think the compiler is optimizing the method call away although I didn't bother checking the bytecode.)




Dennis: Back to your point. I wouldn't use a setter for the one line, but I don't think it is a bad to do so. I really think it is personal preference.
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 31069
    
232

Steve,
I started my post before I saw yours. Then the phone rang. Then I finished it and saw you had already done the work. I posted anyway since two benchmarks can't hurt.
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 31069
    
232

I was still curious so I looked at the bytecode. It is indeed different (see line 6) yet the performance wasn't significant.





Adam Michalik
Ranch Hand

Joined: Feb 18, 2008
Posts: 128
The bytecodes are different, because such optimizations are done by the VM (the JIT compiler). The assignments may be inlined then in the native code.

By the way, my opinion on the argument is that: first, object-oriented programming is all about method calls, as they are the accomplishment of the basic concepts: encapsulation, virtual calls, inheritance etc. So in my opinion the last thing one should consider is the cost of the call (putting some parameters on the stack, a jump instruction, a return instruction) when the OO design should be the main goal. If really a few nanoseconds matter, why not switch to coding in assembler ?

Premature optimization is the root of all evil (or at least 95% of all evil)
Dennis Korbar
Greenhorn

Joined: Jan 14, 2009
Posts: 20
Gosh, this has become quite a discussion.
Thanks for all the input, I really appreciate that.

I have to agree that performance shouldn't be much of a problem. However, as stated before, I wasn't at all aware of the problem with subclasses overriding my setters, so I have put a bit more thought into that, couldn't I do the following to prevent the problem? (Yes, this might be a bit overkill but it should take care of the overriding problem, right?)

And in answer to some of the comments, I'm totally aware that this doesn't make a lot of sense on a one line getter or setter, but the thing is that I don't know if it will still be a one line getter or setter in a year or in two years. And If I have used the getters and setters in the constructor, it'll be one line less to worry about when changing the setter or getter (or the variables restrictions).

Cheers,
Dennis
Jeanne Boyarsky
author & internet detective
Marshal

Joined: May 26, 2003
Posts: 31069
    
232

Dennis,
That removes "the problem", but introduces another. If a subclass decides to overwrite setA, they don't know that _setA exists. Which could lead to some interesting behavior. I think making the setter final is cleaner.
Dennis Korbar
Greenhorn

Joined: Jan 14, 2009
Posts: 20
Hm ok, so I should definetly avoid calling overrideable methods in the constructor? But wouldn't that apply for every other method too?

What if I have something like the following:

so if the subclass' author decides to override the second doSomething, I'll have a similar problem if someone calls the first doSomething.
So by design, the second doSomething actually needs to be final in order to avoid unpredictable behaviour? (Method overloading is probably a bad example for this, but the first that came to mind, it could be any other method call too.)

Don't get me wrong, I'm in no way trying to criticize or so, I'm merely trying to understand how to write cleaner and more sustainable code.

Cheers,
Dennis
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Dennis Korbar wrote:Hm ok, so I should definetly avoid calling overrideable methods in the constructor? But wouldn't that apply for every other method too?


No, not really. The problem with calling overrideable methods in the constructor is that the constructor is responsible for building the instance of the class. The instance is not complete until the constructor is completed. By using a method call in the constructor that a child type could override you are allowing the child class to modify how the parent class gets built. This can lead to improperly build instances of the parent class, and can also lead errors injected into child class because it would expect the parent to be completely built before doing any work. For example:


Child's setA() would be called prior to the Parent's setB(), yet Child's setA() requires b to be set properly for the validation to work. As a result, Child code breaks because it is called prior to the completion of Parent instance construction, which would not be obvious to anyone trying to override Parent. There are lots of other nastier things that can happen, like null pointer exceptions that 'should be impossible', setting derived values that get changed when parent class construction completes and end up with inconsistent states in the Child class, etc...

Method calls from inside other method calls may have the same problems, and if they do then the method being called should be protected from being overriden. But they do not lend themselves to the same level of possible mishap that calling a setter method from inside a constructor would.
Rusty Shackleford
Ranch Hand

Joined: Jan 03, 2006
Posts: 490
Apologies for resurrecting a somewhat old thread. Been very busy.

Bear Bibeault wrote:Still not buying it. You'll have to put some significant numbers behind your argument. Violating precepts of encapsulation because of a phantom performance concern is the epitome of premature optimization. I find it difficult to believe you can prove that the use of setters will create a demonstrable and perceivable difference in performance.

There may be no arguing that a method call will be more "expensive" than an assignment, but to argue that design decisions should be made based upon such negligible differences is where I differ.

Moreover, setters are mandatory in many environments where the JavaBean pattern must be adhered to for things to work properly.



I am curious how you think this:

public MyClass(int a, int b) {
setA(a);
setB(b);
}

Is better then

public MyClass(int a, int b) {
this.a=a;
this.b=b;
}

Encapsulation is not violated in any way and in fact you call this constructor more than a handful of times and performance will be significantly impacted. You gain absolutely nothing by calling setter with no validation in the constructor.

I am not saying don't use setters, not sure how this strawman came to life, I am saying that using them in this way is wasteful. In fact, using them could be considered premature throttling.



When run with 10,000 assignments there is usually less than 100ns difference in times (and it flip-flops on which type of calls are faster - methods or direct assignment) - this suggests to me no difference between the two. When I ran it with 100,000 assignments there averages about 400ns difference in times (the method calls are typically longer than direct assignments). So with enough method calls, then perhaps a small difference can be measured but to program against this difference is a waste of thought processes.

The choice between using methods or not should be based on considerations other than speed.


There is absolutely no reason to consider calling non-validating setters in the constructor. JIT compilers can erase many poor programming choices, but it shouldn't be used in lieu of writing good code.

Sure there is. Bear and I disagree with you. If you have at least two experienced developers who disagree with a statement, you can't say it is a universal fact that should be accepted without argument.


It is a fact that calling and setting up a method is more costly then assigning a value to a variable. Compare the number of instructions for both, simple CS100 stuff. I would bet quite a bit that the JIT compiler looked at that constructor, shook its head and rewrote it to this.a=a.

Assuming you are comparing the same algorithm. Some recursive algorithms do more work.

The first is an obvious given. The second is true, but a good chuck of the "more work" is what? Methods calls!

Premature optimization is the root of all evil (or at least 95% of all evil)


I agree 100%. However, writing intelligent and clean code is never premature optimization. Is is generally easier to write certain things using recursion, but writing out the iterative version is not premature optimization it is smart programming. Of course sometimes recursion is the way to go, but knowing when and why to use different techniques, algorithms, etc is not something you need a profiler to tell you, it is a "simple" matter of staying awake in algorithm classes.
Joanne Neal
Rancher

Joined: Aug 05, 2005
Posts: 3742
    
  16
Rusty Shackleford wrote:you call this constructor more than a handful of times and performance will be significantly impacted.


significantly ?
You keep saying this, yet you still haven't shown any figures to back this up.
People would be more willing to accept your argument if you showed them some convincing evidence.


Joanne
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Rusty Shackleford wrote:
Encapsulation is not violated in any way and in fact you call this constructor more than a handful of times and performance will be significantly impacted. You gain absolutely nothing by calling setter with no validation in the constructor.


If by "more than a handful" you mean "more than a couple hundred thousand" perhaps you make a point. Still, the examples posted show that the performance difference is negligible. Do you have statistics or examples that suggest a 'handful' of method calls is significantly more expensive than a 'handful' of direct assignments?

As for what you gain - the main part of what you would gain is a sort of 'future-proof'. If you change how data is stored or add in validation, or add some sort of event publishing code to the value being set, you can make the change once in the set method, rather than have to duplicate it in both the set method and the ctor, or remember that now you have to change the ctor to call the set method. A trivial change, but if you need to do it you only need to forget once and you have a bug in your app.

I personally tend towards direct assignment unless I feel reasonably sure something in how the value gets stored will change but I understand the call from the constructor and I see it as personal preference or situational rather than a paradigm. My only points are that 1) there is a reason and 2) Performance is not an issue.


The choice between using methods or not should be based on considerations other than speed.


There is absolutely no reason to consider calling non-validating setters in the constructor. JIT compilers can erase many poor programming choices, but it shouldn't be used in lieu of writing good code.


I disagree with the no-point argument (as described above) and if the JIT compiler can optimize it, then there is no point in avoiding it (except personal preference of what 'good code' looks like), again, unless something else comes into play.


Sure there is. Bear and I disagree with you. If you have at least two experienced developers who disagree with a statement, you can't say it is a universal fact that should be accepted without argument.


It is a fact that calling and setting up a method is more costly then assigning a value to a variable. Compare the number of instructions for both, simple CS100 stuff.


Evidence shown here indicates the difference is minimal. So minimal as to be not a consideration for the choice.

I would bet quite a bit that the JIT compiler looked at that constructor, shook its head and rewrote it to this.a=a.


1) The JIT compiler makes no value judgements, it just does its job. It is you who is making the value judgement here (just to be clear)
2) (I know I am repeating myself here... sorry) If the JIT can optimize it to be the same, then why not let it? You get the 'safety' of method calls in source code, and you get the speed of direct assignment. What's the problem?


Premature optimization is the root of all evil (or at least 95% of all evil)


I agree 100%. However, writing intelligent and clean code is never premature optimization.


And I guess your definition of intelligent and clean code is different than others. You definition includes directly assigning variables unless otherwise necessary (like validation). I don't disagree with you. Others think intelligent code means simplifying future maintenance - which in part is done by consolidating all the code that is used to set a value into a single method.

The problem that came up here is that you say your 'clean and intelligent' code is significantly faster than what others are saying. If it were true, then it would be real point of consideration - people would re-consider what they think 'good code' looks like. But I think we showed simple benchmarks where it isn't significantly faster, and that any speed increase would be in the realm of 'premature optimization'. Furthermore you even theorize that the differences are trivialized away by the JIT compiler. So this claim that your 'clean and intelligent' code is significantly faster has not been help up to be true.

So premature optimization not-withstanding, I still think the difference between using setters or not is about personal preferences and other requirements.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Best Practice for getters and setters