package net.sf.beanlib.utils; 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; //http://gafter.blogspot.com/2006/12/super-type-tokens.html /** * References a generic type. * * @author crazybob@google.com (Bob Lee) */ public abstract class TypeReference<T> { private final Type type; private volatile Constructor<T> 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. */ public T newInstance() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { if (constructor == null) { @SuppressWarnings("unchecked") Class<T> rawType = type instanceof Class<?> ? (Class<T>) type : (Class<T>) ((ParameterizedType) type).getRawType(); constructor = rawType.getConstructor(); } return 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(); System.out.println(l1); List<?> l2 = new TypeReference<ArrayList<?>>() {}.newInstance(); System.out.println(l2); } }