can I define setter method to return this rather than void?
Like:
ClassA setItem1() {
return this;
}
ClassA setItem2() {
return this;
}
Yes. This is a somewhat common technique called Method Chaining, and can be used to create a "fluent interface".
See: http://en.wikipedia.org/wiki/Method_chaining, http://en.wikipedia.org/wiki/Fluent_interface
After checking the Oracle JavaBean pages I didn't find anything which explicitly tells you that the setters need to be void. Nevertheless all examples have void set-methods.
The PropertyDescriptor in the Java API support non-void setters, so I think it should be pretty safe to let your setters return this. To be on the safe side you should probably check out if the frameworks you intend to use that uses reflection. For instance didn't Spring support non-void setters in xml config prior to version 3.1.
There is a lot of misunderstanding about JavaBeans spec.
The main reason for it's existence is the unified Java "component" model. It's a way to interact programatically with a Java Object using Reflection. The API itself is named JavaBeans Introspection. Please, take a look at example usages and You will know a lot more than an average Java programmer does.
Introspection API can be used to manipulate GUI elements in an unified manner. Your component exposes it's properties as a pairs of getters and setters so that they could be discovered and manipulated at run-time on a GUI builder's property sheet.
So, mixing fluent APIs and JavaBeans Spec in my opinion is a no-go. That's two completely unrelated concepts and can disrupt each other. JavaBeans Introspection might not work when method signature differs (return type).
Take a look at this example (taken from linked tutorial):
public class SimpleBean
{
private final String name = "SimpleBean";
private int size;
public String getName()
{
return this.name;
}
public int getSize()
{
return this.size;
}
public void setSize( int size )
{
this.size = size;
}
public static void main( String[] args )
throws IntrospectionException
{
BeanInfo info = Introspector.getBeanInfo( SimpleBean.class );
for ( PropertyDescriptor pd : info.getPropertyDescriptors() )
System.out.println( pd.getName() );
}
}
This example creates a non-visual bean and displays following properties derived from the BeanInfo object:
You might want to see what happens when You change void
return type to anything else. I have done so and the result is the same. So, does that mean it's allowed?
I'm afraid no. The JavaBeans spec is quite strict about those method signatures. It just happened that implementation is forgiving. Nonetheless, I'd disadvise mixing fluent interface with JavaBeans. You can't really rely that, if the discovery works now, it will also in future.
But, from the other side - it looks like You don't use JavaBeans to full extent. Only the getters/setters pair of method. It's up to You how You implement and design Your APIs.
I would guess this is not in violation of the JavaBean specification, although I am not sure of it.
Check out the following example:
public class JavaBean {
private String value;
public String getValue() {
return value;
}
public JavaBean setValue(String value) {
this.value = value;
return this;
}
public static void main(String[] args) throws Exception {
JavaBean bean = new JavaBean();
JavaBean.class.getMethod("setValue", String.class).invoke(bean, "test");
System.out.println(bean.getValue());
}
}
Many frameworks access JavaBeans using the reflection API. As you can see above, accessing a settter which returns 'this' is not influenced by the return type (the return type is not used to locate a method via reflection). It also makes sense, because you cannot have two methods in one scope that are identical except for their return type.
Absolutely nothing to stop you doing that but why. If you want to do this create a constructor that takes the args. Bare in mind some software that uses beans would not be expecting return values and may have some unexpected results
If you just want to simplify initialisation, (maybe to set up tests) you could use some groovy code.
There is nothing preventing you from providing setter methods which return the target object as a convention in your interface...
However, you must also use the canonical signature for Java Bean Simple Property setter methods (e.g. void setProp(Type t)
) or the bean property will not be recognized as writeable by other software which expects that signature.