类型安全的异构容器
Posted 风来了
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类型安全的异构容器相关的知识,希望对你有一定的参考价值。
原文: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 [email protected] (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(); } }
以上是关于类型安全的异构容器的主要内容,如果未能解决你的问题,请参考以下文章