Java – How to implement a builder class using Generics, not annotations

factory-patterngenericsjavawrapper

I want to write a generic builder class which wraps around any java class and providing setter functions of a specific style. I am not sure if this could be called "dynamically generated functions".

When I have a beanish Pojo class i.e.

class Pojo {
    public void setValue(int value) {...}
    public void setName(String name) {...}
}

My Maker class should be usable like this:

Pojo p = Builder<Pojo>.create(new Pojo())
             .setName("Funny")
             .setValue(123)
             .build();

As you can see, the work it does should be similar to

class PojoBuilder {
    private Pojo pojo;
    PojoBuilder(Pojo pojo) { this.pojo = pojo; }
    public static PojoMaker create(Pojo p) { return new PojoBuilder(p); }
    public PojoBuilder setName(String name) { pojo.setName(name); return this; }
    public PojoBuilder setValue(int val) { pojo.setValue(val); return this; }
    public Pojo make() { return pojo; }
}

Only, I would like Maker to be generic. Obviously, the "setXyz"-Methods depend on the generic argument. How to do that?

Of course, functionally equivalent but syntactically different approach is also fine.

I'd like to do it without annotations: With annotations I gather I'd need a second javac-pass over my source code, generating the wrapper code. That seems to be what Limbok does or how some JPA wrappers work. But when I work with Mockito it seems that this pass is not necessary. So, How can I do it with Generics?

Best Solution

The easiest way is using Lombok library.

@Value
@Builder
public class MessageEvent<T> {
    T message;
    TypeEnum type;
}

And the usage is like this.

MessageEvent<String> messageEvent = MessageEvent.<String>builder().message("test").build();