Question

I have a number of set methods setup and using a constructor to initiate their value as follows. It is working but I am concerned as to whether it is a normal Java convention to do so (is it normal to call a set method inside a constructor?).

The alternative way I can think of is to call an empty constructor and call the set methods one by one in the main method to set the value. I find this second method tedious. Please advice if what I have done is fine/ within Java convention or if there is a better way to do it. Do tell if I need to post more code to make my question more clearer. I can post it all if it would make better sense. Thank you.

public Person(String foreName,String surName, int age, double height, String gender){
        personCount++; 
        setForeName(foreName);
        setSurName(surName);
        setAge(age);
        setHeight(height);
        setGender(gender); 
    }
Was it helpful?

Solution 2

It's not just a matter of taste. If there isn't any extra logic in the setXXX() methods, the convention is to assign the attributes directly in the constructor:

this.foreName = foreName;
this.surName = surName;

... And so on. But if there is extra logic in the setXXX() methods, then you should use them as required. Say, a call to logging logic or similar:

public void setForeName(String pForeName) {
    log.info("setting new foreName value: " + pForeName);
    this.foreName = pForeName;
}

See how the last line in setForeName() is the same as performing a direct assignment? Also notice that calling a setXXX() might have a very, very small cost in performance (most likely optimized away by the JIT compiler). Under normal circumstances you should optimize for readability and clarity above all, and IMHO using a direct assignment here is the preferred option.

OTHER TIPS

If using this doesn't bypass the validation rules defined in the setters, it's just a matter of taste:

public Person(String foreName,String surName, int age, double height, String gender){
    personCount++; 
    this.foreName = foreName;
    //same goes for the rest of the params
}

Keep in mind that setters are exposed to the public, which means it can be overriden by its subclasses. When you create a subclass with the intent of modifying the behavior of one of its setters, the first thing that it will do in the construtor of the subclass is to call its superclass' constructor, which means that these setters and the added logic inside it will be executed when in fact you actually want modify the behavior of one of its setters. This kind of problems are often times hard to spot.

A quote from Effective Java Item 17

Constructors must not invoke overridable methods, directly or indirectly. If you violate this rule, program failure will result. The superclass constructor runs before the subclass constructor, so the overriding method in the subclass will get invoked before the subclass constructor has run. If the overriding method depends on any initialization performed by the subclass constructor, the method will not behave as expected.

It's perfectly fine to use set methods in the constructor. I don't know if it's really a convention to do it with this.var = var, but it's fine.

I don't see any problem in calling a setter in a constructor. In fact, if you plan to have setters carry additional logic, using the method gives you better encapsulation.

why are you call set method inside constructor ? try this

private String foreName;
private String surName;
private int age;
private double height;
private String gender


public Person(String foreName,String surName, int age, double height, String gender){
        personCount++; 
        this.foreName = foreName;
        this.surName = surName;
        this.age = age;
        this.height = height;
        this.gender = gender; 
    }

/// setter and getter methods of above private variables..

What I've been taught to do thus far is to provide the setters and getters within the constructor, then actually set and get it within whatever method, (in your case main), that you want to use it for. But, that's if your fields are private. If they're public like in your case, then I would say setting your variables in the field or constructor, then calling them where/whenever you want to use them makes much more sense...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top