Reputation: 23978
I am working on a Java project after a period using C++ and C#, and I have a doubt about best practices for field initialization in constructors. Basically, suppose I have a simple Point class. In C++ my field initialization in the constructor would look like:
class Point {
public:
// Default constructor
Point(double x, double y) : x(x), y(Y) { }
protected:
// Coordinates
double x, y;
};
In C# ...
class Point {
// Coordinates, with automatic properties
public double X { get; protected set; }
public double Y { get; protected set; }
// Default constructor
Point(double x, double y) {
X = x;
Y = y;
}
}
In Java ... best practices would suggest to define getters / setters for fields which must be accessed from the outside. But it is advisable to use them from inside the class as well? The doubt comes from the fact that Eclipse seems comfortable with converting each this.field = field
in the class code to setField(field)
for fields which have getters / setters, even if I reading / writing happens from inside the class code (therefore I wouldn't need to use the class interface).
This basically adds up a function call for each access. Now, apart from the case in which setting a field involves some other operation (i.e. validations, processing, etc.) has this any sense? Common sense would suggest that using getters / setters is similar to using C# properties, but here I am specifically questioning about C#'s automatic properties which only involve basic access, without any processing. So the question is: is there any good in calling getters / setters with no additional processing from inside the class code?
Thank you
Tunnuz
Upvotes: 1
Views: 4765
Reputation: 13468
The use of a setter could be recommendable if you are going to do some validation, formatting, or processing on the value to set.
Let's suppose that you need your class Foo always need having a not empty bar value, when not using the setter, you'll need to rewrite the validation code every time you set the value:
public class Foo {
private String bar;
public Foo(String aValue) {
if(aValue==null || aValue.equals("")) {
throw new IllegalArgumentException("Duh");
}
bar=aValue;
}
public void setBar(String aValue) {
if(aValue==null || aValue.equals("")) {
throw new IllegalArgumentException("Duh");
}
bar=aValue;
}
}
Using the setter, you reuse code, and allow to implement more logic in just one point:
public class Foo {
private String bar;
public Foo(String aValue) {
setBar(aValue);
}
public void setBar(String aValue) {
if(aValue==null || aValue.equals("")) {
throw new IllegalArgumentException("Empty values not allowed");
}
if(aValue.length()>24) {
throw new IllegalArgumentException("Too long");
}
bar=aValue;
}
}
Upvotes: 1
Reputation: 240860
Getters Setters encapsulates the things. Today there is nothing to process but tomorrow you may need to process something. so its better to use Getters Setters.
For default value initilization you can use constructor.\ but if there is some processing while setting getting use Getters Setters.
Best practices is to use
Also See
Upvotes: 4
Reputation: 38759
I would also prefer direct access. However, for non-trivial get/setters you may want to be using them if the internals also require the non-trivial semantics.
If you don't know in advance that the get/setters will be non-trival, then you also probably don't know in advance whether the internals should also be performing the additional work, so premature encapsulation isn't as useful as it might appear.
My Eclipse (Helios) installation doesn't do this transformation so I assume you can turn it off.
Upvotes: 2
Reputation: 1942
As I've been taught, using getters and setters inside the constructor is unnecessary, and only creates extra method calls to slow down your program. I'm not sure how important that is though, since such method calls are usually inlined at compile-time.
Upvotes: 0