Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I have an abstract builder class in java with method chaining without doing unsafe operations?

I'm trying to have an abstract base class for some builder classes so I can easily reuse code between the Builder implementations. I want my builders to support method chaining therefore a method has to return "this" instance of the most specific type. I figured I could probably do this with generics. Unfortunatly I did not manage to do it without using unsafe operations. Is it possible?

Sample code of how I'm trying it (and how it works) below. I'd like to avoid casting to T in "foo()" (which causes an unchecked warning), can this be done?

public class Builders {    public static void main( final String[] args )    {       new TheBuilder().foo().bar().build();    } }   abstract class AbstractBuilder<T extends AbstractBuilder<?>> {    public T foo()    {       // set some property       return (T) this;    } }   class TheBuilder extends AbstractBuilder<TheBuilder> {    public TheBuilder bar()    {       // set some other property       return this;    }     public Object build()    {       return new Object();    } } 
like image 948
Patrick Huy Avatar asked Apr 28 '11 12:04

Patrick Huy


People also ask

Can an abstract class have all methods unimplemented?

An abstract class can have one or multiple number of unimplemented methods. As an abstract class is not proper, or does not have ideally defined methods compared to a regular class, so abstract classes cannot be instantiated, that means we cannot create any direct objects of abstract classes.

Can an abstract class contain any method implementations?

Abstract class in Java is similar to interface except that it can contain default method implementation. An abstract class can have an abstract method without body and it can have methods with implementation also. abstract keyword is used to create a abstract class and method.

What are the rules for abstract classes in Java?

Abstract class: is a restricted class that cannot be used to create objects (to access it, it must be inherited from another class). Abstract method: can only be used in an abstract class, and it does not have a body. The body is provided by the subclass (inherited from).

Which type of class Cannot contain abstract operations?

A normal class(non-abstract class) cannot have abstract methods.


1 Answers

You want to declare T as extends AbstractBuilder<T> in AbstractBuilder.

Use an abstract protected method to get this of type T.

abstract class AbstractBuilder<T extends AbstractBuilder<T>> {     protected abstract T getThis();      public T foo() {         // set some property         return getThis();     } }   class TheBuilder extends AbstractBuilder<TheBuilder> {     @Override protected TheBuilder getThis() {         return this;     }     ... } 

Alternatively, drop the generic type parameter, rely on covariant return types and make the code cleaner for clients (although usually they would be using TheBuilder rather than the largely implementation detail of the base class), if making the implementation more verbose.

like image 180
Tom Hawtin - tackline Avatar answered Sep 22 '22 21:09

Tom Hawtin - tackline