如题:已知一个 关于类型的字符串(如“Map>”),现在需要根据这个字符串,获得一个Map>对象和该对象的Type?
Map和List 都是接口,要从字符串"Map>"获得一个Map>对象?问题本身有问题,实例是HashMap>还是TreeMap>还是其他的实现。。。
public static void main(String[] args) throws Exception { Map<String, List<String>> b = getInstance("Map<String, List<String>>");
System.out.println(b.getClass());
}
public static <T> T getInstance(String type) throws Exception {
Class clazz = Class.forName(getClassName(type));
return (T) clazz.newInstance();
}
private static String getClassName(String type) {
if (type.startsWith("Map"))
return "java.util.HashMap";
return "java.lang.Object";
}
java泛型的类型应该不包括参数的类型,编译后被擦除了
[quote]获得一个Map>对象和该对象的Type[/quote]
获得是指 新建 一个这种类型的变量么?
另外,“该对象的TYPE”不就是 Map> 么?
[code="java"]package dl.java.iteye;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class GenericRelection {
/**
* java程序中,已知字符串Map<List<String>> 如何获取它的 Type 问题没有描述清楚, 更准确的说是,已经知道
* 字符串为“Map<List<String>> ”, 如何根据字符串获取到对应的泛型类的Type? 跪拜,请各位大神赐教!
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 简单点说就是根据“Map<List<String>>
* ”创建 Map<List<String>> 对象。
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
*
* @param args
* @throws NoSuchMethodException
* @throws SecurityException
* @date 2011-09-04
*/
public static void main(String[] args) throws SecurityException,
NoSuchMethodException {
// TODO Auto-generated method stub
// 定义一个Map
Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
// 声明List对象
List<String> list = new ArrayList<String>();
// 向List中添加数据
list.add("Tomcat");
list.add("JAVA");
list.add("JavaScript");
// 向Map添加数据
map.put(1, list);
/***********************************************************************
* 通过 Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
* 这样的声明语句,是不能知道泛型参数化列表到底存的是什么类型的数据 因为JVM编译成class字节码时已经是去泛型参数化,即: Map<Integer,
* List<String>> map = new HashMap<Integer, List<String>>(); 和 Map<Integer,
* String> map2 = new HashMap<Integer, String>(); 生成的字节码一样 如下可以测试出字节码
*/
Map<Integer, String> map2 = new HashMap<Integer, String>();
System.out.println(map.getClass() == map2.getClass());// 返回true,说明字节码一样,
System.out.println();
/***********************************************************************
* 可通过方法对象Method获取泛型参数化列表数据
*
*
*/
Method method = GenericRelection.class.getMethod("use", Map.class);
Type[] types = method.getGenericParameterTypes();
// 循环获取参数化列表数据类型
for (Type type : types) {
// ParameterizedType 表示参数化类型,如 Collection<String>。
ParameterizedType pType = (ParameterizedType) type;
// 获取原始类型即:调用发放参数类型如use方法参数类型,打印出
// interface java.util.Map
System.out.println(pType.getRawType());
// 获取此类型的实际类型参数的 Type 对象的数组
Type[] typess = pType.getActualTypeArguments();
for (Type item : typess) {
// 打印,参数列表类型
// class java.lang.Integer
// java.util.List<java.lang.String>
System.out.println(item.toString());
// System.out.println(item.getClass().getName());
}
}
/***********************************************************************
* 打印结果:如下
* interface java.util.Map
* class java.lang.Integer
* java.util.List<java.lang.String>
*
* 通过某个方法是可以知道方法参数的泛型参数类型,因为我们一般是把泛型当成一个参数,然后在方法中处理
* 业务。
* 注意:单独我Map<Integer, List<String>> map = new HashMap<Integer, List<String>>();
* 这种形式的处理,很难获取其泛型参数类型
* 故而使用下面的use(Map<Integer, List<String>> map) 通过反射知道
*/
/***********************************************************************
* 总结:如果想获取某个泛型参数类型,需要通过调用声明的泛型类型进行反射获取。 Hibernate即通过这种方法获取泛型参数类型。
*/
}
/**
* 使用泛型
*
* @param map
*/
public static void use(Map<Integer, List<String>> map) {
}
}
/*******************************************************************************
[/code]
[code="java"]Type type = new TypeToken>>() {}.getType();[/code]
既然你是通过TypeToken构造函数传递到这个类中的一个Map>对象,你仔细阅读上面代码,可以对这个构造函数进行反射处理,获取Map>参数类型。