让java中的setter返回“this”是好还是坏?

public Employee setName(String name){
   this.name = name;
   return this;
}

这个模式很有用,因为你可以像这样设置链:

list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));

而不是这样:

Employee e = new Employee();
e.setName("Jack Sparrow");
...and so on...
list.add(e);

...但这有点违背标准惯例。我认为这是值得的因为它可以让setter做一些其他有用的事情。我曾在一些地方看到过这种模式(例如JMock、JPA),但它似乎并不常见,而且通常只用于定义良好的api,在这些api中这种模式随处可见。

更新:

我所描述的显然是有效的,但我真正想要的是一些关于这是否被普遍接受的想法,以及是否存在任何陷阱或相关的最佳实践。我知道Builder模式,但它比我所描述的要复杂一些——正如Josh Bloch所描述的,有一个用于对象创建的相关静态Builder类。


当前回答

因为它不返回void,所以它不再是一个有效的JavaBean属性setter。如果您是世界上使用可视化“Bean Builder”工具的7个人之一,或者是使用JSP-bean-setProperty元素的17个人之一,那么这可能很重要。

其他回答

从声明中

list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));

我看到两件事

1)毫无意义的话。 2)缺乏可读性。

这个方案(双关语),称为“流畅界面”,现在变得非常流行。还可以接受,但不是我的菜。

这种特殊的模式称为方法链接。维基百科的链接,这有更多的解释和例子,如何在各种编程语言中完成。

附注:只是想把它留在这里,因为我正在寻找具体的名字。

第一眼看到:“可怕!”

进一步思考

list.add(new Employee().setName("Jack Sparrow").setId(1).setFoo("bacon!"));

实际上更不容易出错

Employee anEmployee = new Employee();
anEmployee.setName("xxx");
...
list.add(anEmployee);

非常有趣。添加想法toolbag…

是的,我认为这是个好主意。

如果我能补充点什么,关于这个问题:

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;
    }
}

这是可行的:

new Friend().setNickName("Bart").setName("Barthelemy");

Eclipse将不接受这一点!:

new Friend().setName("Barthelemy").setNickName("Bart");

这是因为setName()返回People而不是Friend,并且没有PeoplesetNickName。

我们如何编写setter来返回SELF类而不是类名呢?

这样就可以了(如果SELF关键字存在的话)。这真的存在吗?

class People
{
    private String name;
    public SELF setName(String name)
    {
        this.name = name;
        return this;
    }
}