首页 > 代码库 > 类型安全的异构容器
类型安全的异构容器
原文:http://gafter.blogspot.com/2006/12/super-type-tokens.html
1. 泛型通常用于集合,如Set和Map等。这样的用法也就限制了每个容器只能有固定数目的类型参数,一般来说,这也确实是我们想要的。
然而有的时候我们需要更多的灵活性,如数据库可以用任意多的Column,如果能以类型安全的方式访问所有Columns就好了,幸运的是
有一种方法可以很容易的做到这一点,就是将key进行参数化,而不是将容器参数化,见以下代码
1 public class Favorites { 2 private Map<Class<?>, Object> favorites = new HashMap<Class<?>, Object>(); 3 public <T> void setFavorite(Class<T> klass, T thing) { 4 favorites.put(klass, thing); 5 } 6 public <T> T getFavorite(Class<T> klass) { 7 return klass.cast(favorites.get(klass)); 8 } 9 public static void main(String[] args) { 10 Favorites f = new Favorites(); 11 f.setFavorite(String.class, "Java"); 12 f.setFavorite(Integer.class, 0xcafebabe); 13 String s = f.getFavorite(String.class); 14 int i = f.getFavorite(Integer.class); 15 } 16 }
2.不足之处
There is a limitation to this pattern. Erasure rears its ugly head:
Favorites:15: illegal start of expression f.setFavorite(List<String>.class, Collections.emptyList());
3.改进
import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; /** * References a generic type. * * @author crazybob@google.com (Bob Lee) */ public abstract class TypeReference<T> { private final Type type; private volatile Constructor<?> constructor; protected TypeReference() { Type superclass = getClass().getGenericSuperclass(); if (superclass instanceof Class) { throw new RuntimeException("Missing type parameter."); } this.type = ((ParameterizedType) superclass).getActualTypeArguments()[0]; } /** * Instantiates a new instance of {@code T} using the default, no-arg * constructor. */ @SuppressWarnings("unchecked") public T newInstance() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { if (constructor == null) { Class<?> rawType = type instanceof Class<?> ? (Class<?>) type : (Class<?>) ((ParameterizedType) type).getRawType(); constructor = rawType.getConstructor(); } return (T) constructor.newInstance(); } /** * Gets the referenced type. */ public Type getType() { return this.type; } public static void main(String[] args) throws Exception { List<String> l1 = new TypeReference<ArrayList<String>>() {}.newInstance(); List l2 = new TypeReference<ArrayList>() {}.newInstance(); } }
类型安全的异构容器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。