Is it a good or bad idea to make setters in java return \"this\"?
public Employee setName(String name){
this.name = name;
return this;
}
Bad habit: a setter set a getter get
what about explicitly declaring a method, that does it for U
setPropertyFromParams(array $hashParamList) { ... }
If you don't want to return 'this'
from the setter but don't want to use the second option you can use the following syntax to set properties:
list.add(new Employee()
{{
setName("Jack Sparrow");
setId(1);
setFoo("bacon!");
}});
As an aside I think its slightly cleaner in C#:
list.Add(new Employee() {
Name = "Jack Sparrow",
Id = 1,
Foo = "bacon!"
});
Yes, I think it's a good Idea.
If I could add something, what about this problem :
class People
{
private String name;
public People setName(String name)
{
this.name = name;
return this;
}
}
class Friend extends People
{
private String nickName;
public Friend setNickName(String nickName)
{
this.nickName = nickName;
return this;
}
}
This will work :
new Friend().setNickName("Bart").setName("Barthelemy");
This will not be accepted by Eclipse ! :
new Friend().setName("Barthelemy").setNickName("Bart");
This is because setName() returns a People and not a Friend, and there is no PeoplesetNickName.
How could we write setters to return SELF class instead of the name of the class ?
Something like this would be fine (if the SELF keyword would exist). Does this exist anyway ?
class People
{
private String name;
public SELF setName(String name)
{
this.name = name;
return this;
}
}
This scheme (pun intended), called a 'fluent interface', is becoming quite popular now. It's acceptable, but it's not really my cup of tea.
It's not bad practice. It's an increasingly common practice. Most languages don't require you to deal with the returned object if you don't want to so it doesn't change "normal" setter usage syntax but allows you to chain setters together.
This is commonly called a builder pattern or a fluent interface.
It's also common in the Java API:
String s = new StringBuilder().append("testing ").append(1)
.append(" 2 ").append(3).toString();
It not only breaks the convention of getters/setters, it also breaks the Java 8 method reference framework. MyClass::setMyValue
is a BiConsumer<MyClass,MyValue>
, and myInstance::setMyValue
is a Consumer<MyValue>
. If you have your setter return this
, then it's no longer a valid instance of Consumer<MyValue>
, but rather a Function<MyValue,MyClass>
, and will cause anything using method references to those setters (assuming they are void methods) to break.