Win a copy of Programmer's Guide to Java SE 8 Oracle Certified Associate (OCA) this week in the OCAJP forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Constructor that returns self

 
Warren Bell
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have seen in some apis the use of constructors that return themselves. Wicket uses this a lot. I have wanted to write these type of constructors in my own classes. I started to play around with it but have not tested it yet. Here is what I have come up with. I am not sure it will even work.


public class Foo
{

private String fooString;

public Foo Foo()
{
super();
return this;
}

// not sure if this will be ok to use instead of public void setFooString(String fooString), since it is needed to conform to the java bean spec.

public Foo setFooString(String fooString)
{
this.fooString = fooString;
return this;
}

Rest of class ...
}

Use it like this:

return (new Foo()).setFooString("something");

What is the correct way to use this kind of pattern?

Thanks,

Warren
 
Ulf Dittmer
Rancher
Posts: 42968
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A constructor always returns the newly constructed object instance. It does not have a return statement, and there's nothing else you need to do for it to return the new object.
 
Warren Bell
Ranch Hand
Posts: 56
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I understand that. Maybe I did not explain my self very good. I am talking about the chaining of methods like this:

(new Foo()).setFooString1("something1").setFooString2("something2").setFooString3("something3");

The setters are returning the object. But this means they do not follow the bean definition, or do they?

Wicket uses this a lot. How is this being done?
 
Ulf Dittmer
Rancher
Posts: 42968
73
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's being done like you suspected, using "return this". There are very different opinions out there whether this is good or bad style. It does make for shorter code, but it's also harder to read (IMO). And yes, it's not JavaBean-style.

I've never used the idiom, and I don't see it often used elsewhere. I take that as an indication that it doesn't have a huge following.
 
David Newton
Author
Rancher
Posts: 12617
IntelliJ IDE Ruby
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This pattern is used extensively by things like Hibernate, various mocking libraries, JavaScript (like jQuery) and other so-called "fluent" interfaces.

Using *only* a fluent-style API is definitely not JavaBean-compatible and can actively screw up things expecting true beans. However, it's usually not JavaBean-style setters that return "this"--the "set" prefix is generally left off. So a Person object might be both JavaBean- and fluent-ish:Personally I don't find it difficult to read, but I come from a Smalltalk background where such message chaining is commonplace--when this pattern started becoming popular with Java I thought it was a Good Thing, although it's abused sometimes:IMO you should just learn regex, which is already a decent, if compact, DSL.
 
Mike Simmons
Ranch Hand
Posts: 3090
14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
A few additions:

These methods are not constructors. Calling them constructors will just create confusion.

The term "fluent interface" was coined by Martin Fowler and Eric Evans, here. Methods that return "this" are a common feature of fluent interfaces, but not the only one. Read the article for more info.

java.util.regex.Pattern and java.util.Scanner are two mainstream Java classes that use this style, as well.

And while they're still not that common in the Java programming world, some projects use them extensively, and some companies as well. We use them all the time where I work, for example.

Recently there's been some interest in a possible minor language change for JDK 7 which might support this more directly, by having the compiler infer a "return this" at the end of any method that currently returns void. Thus, all existing conventional setters would automatically return this, without us programmers needing to rewrite any code. I think it sounds like a nice idea. But last I heard, it probably won't make it into JDK 7. (Like most other cool features, it seems.)


 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic