I am designing a simple Data Access Object for my Java application. I have a few classes (records) that represents a single row in tables like User
and Fr
It looks like you want to adapt what Josh Bloch calls a Typesafe Heterogenous Container pattern: you are passing a type token Class
, and you want back a List
.
Plain old THC can map a Class
to a T
in a typesafe manner, but since you actually want a List
instead, then you want to use what Neal Gafter calls the super type tokens.
The following snippet is adapted from Crazy Bob Lee's code posted in Neal Gafter's blog:
public abstract class TypeReference {
private final Type type;
protected TypeReference() {
Type superclass = getClass().getGenericSuperclass();
if (superclass instanceof Class>) {
throw new RuntimeException("Missing type parameter.");
}
this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0];
}
public Type getType() {
return this.type;
}
}
Now you can create a super type token like these:
TypeReference stringTypeRef =
new TypeReference(){};
TypeReference integerTypeRef =
new TypeReference(){};
TypeReference> listBoolTypeRef =
new TypeReference>(){};
Essentially you pass a TypeReference
instead of a Class
. The difference is that there is no List
, but you can make a TypeReference
.>
So now we can make our container as follows (the following is adapted from Josh Bloch's original code):
public class Favorites {
private Map favorites =
new HashMap();
public void setFavorite(TypeReference ref, T thing) {
favorites.put(ref.getType(), thing);
}
public T getFavorite(TypeReference ref) {
@SuppressWarnings("unchecked")
T ret = (T) favorites.get(ref.getType());
return ret;
}
}
Now we can put the two together:
Favorites f = new Favorites();
f.setFavorite(stringTypeRef, "Java");
f.setFavorite(integerTypeRef, 42);
f.setFavorite(listBoolTypeRef, Arrays.asList(true, true));
String s = f.getFavorite(stringTypeRef);
int i = f.getFavorite(integerTypeRef);
List list = f.getFavorite(listBoolTypeRef);
System.out.println(s); // "Java"
System.out.println(i); // "42"
System.out.println(list); // "[true, true]"
Neal Gafter argued in his blog that with some more bells and whistles, TypeReference
for super type tokens will make a worthy inclusion in the JDK.