Now I read quite a bit of Java code but I always make an effort to understand each bit of code that passes by my desk and I do still get some surprises. Whilst looking at some jersey client code I noticed the following line.
public List<StatusBean> getFriendsTimelineJson() { return wr.path("statuses/friends_timeline.json") .header(AUTHENTICATION_HEADER, authentication) .accept(MediaType.APPLICATION_JSON_TYPE) .get(new GenericType<List<StatusBean>>() { }); }
Note the final parameter in the builder that take a instance of "GenericTypeList" which appears to be some kind of anonymous type. It turns out to be a clever workaround for generic type erasure.
Consider the following method:
public <T> T getFavorite(Class<T> klass) { return ...; }
Type erasure means the following won't compile:
List<String> list = thing.getFavourite(List<String>.class);
Using a "super type token" solve this problem as generic types are not erased from class definitions, so you can write:
List<String> list = thing.getFavourite( new GenericType<List<String>>() {});
With the following implementation of the getFavourite method: (See GenericType.java)
public <T> T getFavorite(GenericType<T> klass) { return getFavourite(klass.getRawClass()); }
You can also see this used in fest-reflect API for the same reasons. (TypeRef in the FEST API example)
2 comments:
Templates have always made my head hurt since C++ at University. Thanks for giving me a headache :).
My pleasure, :-)
Gerard
Post a Comment