junsheng100
2011-09-05 13:48
浏览 239
已采纳

java如何反转泛型?

如题:已知一个 关于类型的字符串(如“Map>”),现在需要根据这个字符串,获得一个Map>对象和该对象的Type?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • _1_1_7_ 2011-09-05 15:49
    已采纳

    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泛型的类型应该不包括参数的类型,编译后被擦除了

    已采纳该答案
    打赏 评论
  • rainbow702 2011-09-05 14:23

    [quote]获得一个Map>对象和该对象的Type[/quote]
    获得是指 新建 一个这种类型的变量么?
    另外,“该对象的TYPE”不就是 Map> 么?

    打赏 评论
  • 赵子阳 2011-09-05 14:55

    [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]

    打赏 评论
  • 赵子阳 2011-09-05 15:13

    [code="java"]Type type = new TypeToken>>() {}.getType();[/code]
    既然你是通过TypeToken构造函数传递到这个类中的一个Map>对象,你仔细阅读上面代码,可以对这个构造函数进行反射处理,获取Map>参数类型。

    打赏 评论

相关推荐 更多相似问题