Can I call methods in constructor in Java?
Can I put my method readConfig() into constructor?
Invoking a not overridable method in a constructor is an acceptable approach.
While if the method is only used by the constructor you may wonder if extracting it into a method (even private
) is really required.
If you choose to extract some logic done by the constructor into a method, as for any method you have to choose a access modifier that fits to the method requirement but in this specific case it matters further as protecting the method against the overriding of the method has to be done at risk of making the super class constructor inconsistent.
So it should be private
if it is used only by the constructor(s) (and instance methods) of the class.
Otherwise it should be both package-private
and final
if the method is reused inside the package or in the subclasses.
which would give me benefit of one time calling or is there another mechanism to do that ?
You don't have any benefit or drawback to use this way.
I don't encourage to perform much logic in constructors but in some cases it may make sense to init multiple things in a constructor.
For example the copy constructor may perform a lot of things.
Multiple JDK classes illustrate that.
Take for example the HashMap
copy constructor that constructs a new HashMap
with the same mappings as the specified Map
parameter :
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
int s = m.size();
if (s > 0) {
if (table == null) { // pre-size
float ft = ((float)s / loadFactor) + 1.0F;
int t = ((ft < (float)MAXIMUM_CAPACITY) ?
(int)ft : MAXIMUM_CAPACITY);
if (t > threshold)
threshold = tableSizeFor(t);
}
else if (s > threshold)
resize();
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
K key = e.getKey();
V value = e.getValue();
putVal(hash(key), key, value, false, evict);
}
}
}
Extracting the logic of the map populating in putMapEntries()
is a good thing because it allows :
- reusing the method in other contexts. For example
clone()
andputAll()
use it too - (minor but interesting) giving a meaningful name that conveys the performed logic
You can: this is what constructors are for. Also you make it clear that the object is never constructed in an unknown state (without configuration loaded).
You shouldn't: calling instance method in constructor is dangerous because the object is not yet fully initialized (this applies mainly to methods than can be overridden). Also complex processing in constructor is known to have a negative impact on testability.
Better design would be
public static YourObject getMyObject(File configFile){
//process and create an object configure it and return it
}
- Factory design pattern