tags:

views:

61

answers:

3

In the following code sniplet, I want to specify that:

  1. attachment and handler share a generic type `
  2. <A>'s type only needs to be specified when notify() is invoked
  3. Invoking notify() is optional.

I do not want to force users to specify <A> at class construction time because they might never end up invoking notify().

/**
 * Builder pattern for some asynchronous operation.
 */
public class OperationBuilder
{
  private A attachment = null;
  private CompletionHandler<Integer, A> handler = null;

  public <A> OperationBuilder notify(A attachment, CompletionHandler<Integer, A> handler)
  {
    this.attachment = attachment;
    this.handler = handler;
    return this;
  }

  public abstract build();
}

Is this possible under Java? If not, what would you recommend I do?

UPDATE: I don't need to specify that <A> associated with attachment and handler must be the same <A> associated with notify(). All I'm trying to specify is that attachment and handler must use the same type <A>.

A: 

Is this possible under Java?

No – A would have to be known to the class (since it’s used in a member of said class).

If not, what would you recommend I do?

You probably don’t need the generic type here. Use an interface or Object. If type safety is important for the interface, you may simply use casts.

Konrad Rudolph
+2  A: 
public class OperationBuilder 
{ 
  private Object attachment = null; 
  private Object handler = null; 

  public <A> OperationBuilder notify(A attachment, CompletionHandler<Integer, A> handler) 
  { 
    this.attachment = attachment; 
    this.handler = handler; 
    return this; 
  } 
} 

If you wanted to later use attachment/handler, you'd have to cast them to the appropriate type at that time, which could lead to runtime type-conversion errors.

BlueRaja - Danny Pflughoeft
+2  A: 

The closest thing you can do is to have notify() return a bridge object that is typed with A. Something along these lines:

  public class OperationBuilder
  {

    public Bridge<A> OperationBuilder notify(A a, CompletionHandler<Integer, A> h)
    {
       return new Bridge<A>(a, h);
    }

    protected abstract<A> void build(Bridge<A> b);



    public class Bridge<A>
    {
        private A attachment;
        private CompletionHandler<Integer, A> handler;

        public Bridge(A a, CompletionHandler<Integer, A> h)
        {
           attachment = a;
           handler = h;
        }


        public void build()
        {
           build(this); // Will invoke OperationBuilder.build()
        }               
    }
  }
Itay
Excellent idea!
Gili