users@jsr311.java.net

Re: JSR311: WebAppExc subclasses? and: generic type for MessageBodyWriters

From: Marc Hadley <Marc.Hadley_at_Sun.COM>
Date: Thu, 05 Jun 2008 17:35:15 -0400

I dug up some notes from our last attempt at making Response generic:

// cut down response and builder for illustrative purposes
public class Response<T> {
    public static <T> ResponseBuilder<T> ok() {
        ResponseBuilder<T> ret = ResponseBuilder.newInstance();
        return ret;
    }
    public static class ResponseBuilder<T> {
        protected ResponseBuilder() {}
        @SuppressWarnings("unchecked")
        protected static <T> ResponseBuilder<T> newInstance() {
            return new ResponseBuilder();
        }
        public Response<T> build() {
            return null;
        }
        public <T> Response<T> build(Class<T> type) {
            return null;
        }
    }
}

// this works
ResponseBuilder<String> builder1 = Response.ok();
Response<String> response1 = builder1.build();

// this works too
ResponseBuilder<Integer> builder2 = Response.ok();
Response<Integer> response2 = builder2.build();

//this doesn't work
Response<Boolean> response3 = Response.ok().build();

The problem is the generic type is not being resolved from what is
returned by Response.ok() but from Response.ok().build(). For the
latter the generic type for the builder is '?', and that is what is
being passed to the build() method. IIUC it is a bit like doing this:

ResponseBuilder<?> builder2 = Response.ok();
Response<Integer> response2 = builder2.build();

// We could do this (yuk)
Response<Boolean> response3 = Response.ok().build(Boolean.class);

// We could also do the same with the static method for example (also
yuk):
Response<Boolean> response4 = Response.ok(Boolean.class).build();

We couldn't see how to support this properly with static typing
without resorting to having a class as a parameter of the static
methods on Response (so that the entity is typed correctly).

We could avoid the static type checking and keep things as they are
except change 'class Response' to 'class Response<T>', but it means
the developer could declare 'Response<String>' but add an entity of
type Integer.

Ideally we would be able to express a type like follows:

Response<String> r = Response.ok<String>.().entity("hello").build();

But that isn't (AFAIK) possible today.

Marc.

---
Marc Hadley <marc.hadley at sun.com>
CTO Office, Sun Microsystems.