Похоже, вы хотите адаптировать то, что Джош Блох называет шаблоном Typesafe Heterogenous Container : вы передаете токен типа Class<T>
и хотите получить обратно List<T>
.
Обычный старый THC может сопоставить Class<T>
с T
типобезопасным способом, но поскольку вместо этого вы действительно хотите List<T>
, то вы хотите использовать то, что Нил Гафтер называет токенами супертипа .
Следующий фрагмент адаптирован из кода Сумасшедшего Боба Ли, опубликованного в блоге Нила Гафтера:
public abstract class TypeReference<T> {
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;
}
}
Теперь вы можете создать токен супертипа , подобный следующему:
TypeReference<String> stringTypeRef =
new TypeReference<String>(){};
TypeReference<Integer> integerTypeRef =
new TypeReference<Integer>(){};
TypeReference<List<Boolean>> listBoolTypeRef =
new TypeReference<List<Boolean>>(){};
По сути вы передаете TypeReference<T>
вместо Class<T>
.Разница в том, что List<String>.class
нет, но вы можете сделать TypeReference<List<String>>
.
Так что теперь мы можем сделать наш контейнер следующим образом (следующее адаптировано из исходного кода Джоша Блоха):
public class Favorites {
private Map<Type, Object> favorites =
new HashMap<Type, Object>();
public <T> void setFavorite(TypeReference<T> ref, T thing) {
favorites.put(ref.getType(), thing);
}
public <T> T getFavorite(TypeReference<T> ref) {
@SuppressWarnings("unchecked")
T ret = (T) favorites.get(ref.getType());
return ret;
}
}
Теперь мы можем соединить их вместе:
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<Boolean> list = f.getFavorite(listBoolTypeRef);
System.out.println(s); // "Java"
System.out.println(i); // "42"
System.out.println(list); // "[true, true]"
Нил Гафтер утверждал в своем блоге, что с некоторыми дополнительными прибавками TypeReference
для жетонов супертипа сделает достойное включение вJDK.
Вложения
Ссылки