`
欣仔91
  • 浏览: 1488 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

java泛型反射调用方法体内类型引用问题

阅读更多

自己在写自动化测试工具有关thrift服务自动化测试遇到的问题

首先给大家看一段代码

 

public static void test(List<Long> list){
        System.out.println(list.get(0));
        System.out.println(list.get(0) + 123);
        System.out.println(list.get(0).getClass());
    }

    public static void bugTest1(){
        String json = "[50004172,926513792]";
        for(Method m :ThriftGenUtils.class.getMethods()){
            if("test".equals(m.getName())){
                for(Class<?> pClass : m.getParameterTypes()){
                    Object argCasted = Json.strToObj(json, pClass);
                    try {
                        m.invoke(new ThriftGenUtils(),argCasted);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                    }
                }

            }
        }

    }

 

运行bugTest1

问题:

1 argCasted具体类型为List,其中的泛型具体类型为什么类型?为什么?

2 invoke是否能成功?

3 若invoke成功了,list的泛型具体类型是什么类型?test是否可以成功运行?若不能成功运行,到哪一行出错?报什么错误?为什么?

 

答案:

1 Integer,m.getParameterTypes()获取到的泛型类型是不包括具体类型的,也就是Json.strToOb调用的时候pClass只是传了List,Json转换的时候只知道是数据类型,默认转成Integer,浮点数转为Double。

2 是

3 Integer,不能成功,到+123那一行报类型转换异常Integer不能转换为Long类型,原因是泛型类型擦除。(泛型类型擦除:http://blog.csdn.net/caihaijiang/article/details/6403349 )

 

 

目前的解决方案为获取到泛型类型及具体类型,通过ObjectMapper.getTypeFactory().constructParametricType(clazz,genericClazzes)来获取javaType再来转换成Object对象

改造后,实现的相关代码如下

            Method method = null;
            List<Object> argList = new ArrayList<>();
            for (Method m : clientClazz.getMethods()){
                if(!methodName.equals(m.getName())){continue;}
                method = m;
                Type[] types = m.getGenericParameterTypes();
                Class[] classes = m.getParameterTypes();
                int i = 0;
                for ( Type c: types) {
                    int index = i++;
                    String arg = args[index];
                    if(!(c instanceof ParameterizedType)){
                        String jsonStr = Json.ObjToStr(arg);
                        argList.add(Json.strToObj(jsonStr,classes[index]));
                        continue;
                    }

                    ParameterizedType pt = (ParameterizedType) c;
                    ObjectMapper mapper = new ObjectMapper();
                    Class<?>[] genericClazzes = new Class<?>[pt.getActualTypeArguments().length];
                    int j = 0;
                    for(Type type : pt.getActualTypeArguments()){
                        genericClazzes[j ++] = (Class) type;
                    }
                    JavaType javaType = mapper.getTypeFactory().constructParametricType(classes[index],genericClazzes);
                    Object argCasted = mapper.readValue(arg,javaType);
                    argList.add(argCasted);

                }
                break;

            }
            if ( method != null){
                res = method.invoke(obj,argList.toArray());
            }

 

 

1
0
分享到:
评论

相关推荐

    Java泛型和反射.ppt

    顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。 简单的来说,反射机制指的是程序在...

    反射处理java泛型

    它提供了便捷的访问泛型对象类型(java.reflect.Type)的反射方法。  本文假设你已经了解java反射知识,并能熟练的应用。如果还不了解java反射知识,那么你可以先移步到Oracel反射课程,这可能是你开始学习反射的好...

    泛型dao 泛型dao 泛型dao

    dao接口 : PersonDAO extends GenericDao, Integer&gt; 可以不写代码,方法已经在父类泛型dao里了,这里为了说明:可扩展添加 findByNameExact()方法 子类的附加方法。 泛型daoimpl :GenericDaoImpl, ID extends ...

    java反射知识点

    这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。 我的代码里主要有一下知识点: 1.获取Class对象的三种方式 2.获取构造方法并调用 3.获取成员方法 4.获取成员变量 5.反射数组 6.通过反射...

    Java开发技术大全(500个源代码).

    invokeMethod.java 利用反射机制调用成员方法 listConstructors.java 利用反射机制获取构造器列表 listFields.java 利用反射机制获取成员属性列表 listMethods.java 利用反射机制获取成员方法列表 loadClass....

    Java实验1代码.doc

    本专栏主要为Java程序设计(基础)实验报告和Java程序设计(进阶)实验报告,基础篇有JAVA环境搭建、Java语言基础、方法和数组、面向对象基础、Java常用类、继承与接口、成员访问控制与异常、JavaFX程序设计、Java...

    廖雪峰 Java 教程.doc

    调用构造方法 获取继承关系 动态代理 注解 使用注解 定义注解 处理注解 泛型 什么是泛型 使用泛型 编写泛型 擦拭法 extends通配符 super通配符 泛型和反射 集合 Java集合简介 使用List 编写equals...

    Java 基础核心总结 +经典算法大全.rar

    通过反射调用方法反射的应用场景 Spring 的 IOC 容器反射 + 抽象工厂模式 JDBC 加载数据库驱动类反射的优势及缺陷 增加程序的灵活性破坏类的封装性 性能损耗 代理模式 静态代理与动态代理常见的动态代理实现JDK ...

    Java开发热门常问面试题目资料解答合集40个资料左右.zip

    答:泛型是Java中引入的一个概念,可以用来定义类、方法和接口,使其可以接受任意类型的参数。泛型的作用是增强类型的安全和可读性。 Java中的多态是什么,有什么作用? 答:多态是Java中的一个重要概念,指的是同...

    Java反射机制重点总结

    文章目录Java ReflectionJava反射机制提供的功能Java反射相关的主要APIjava.lang.Class类Class类的核心要点Class类的重要API实例实例化Class类对象(四种方法)创建类对象并获取类的完整结构获取Class对象后创建类的...

    疯狂JAVA讲义

    8.4.2 泛型方法和类型通配符的区别 306 8.4.3 设定通配符的下限 307 8.4.4 泛型方法与方法重载 309 8.5 擦除和转换 310 8.6 泛型与数组 311 8.7 本章小结 313 第9章 与运行环境交互 314 9.1 与用户互动 315 ...

    Java2核心技术.part5

    12.5.3保存对象引用问题的解决 12.5.4理解对象引用的输出格式 12.5.5修改默认的序列化机制 12.5.6单元素与类型安全枚举的序列化 12.5.7版本 12.5.8使用序列化进行克隆 12.6文件管理 12.7新的I...

    java高级特性,涵盖了多种java常用的一些例子

    在运行状态中,对于任意一个类能够获取类中的所有属性和方法,对于任意一个对象能够调用对象中的属性和方法,这种动态获取属性和方法的机制:反射。 设计模式1(单例,工厂) 设计模式2(观察者,适配器) 设计模式...

    Java 基础面试题

    23. 为什么start调用run方法,调用run不会调用start方法 24. 手写单例模式中的懒汉式和饿汉 25. transient 这个关键字是干啥的 26. 什么是一致性hash算法 27. 构造方法链 28. 谈谈你对线程调度的理解 29. JDK...

    虚拟数据层 Struts2、Hibernate、Spring整合的泛型DAO Version 2010.9.27

    dao接口 : PersonDAO extends GenericDao, Integer&gt; 可以不写代码,方法已经在父类泛型dao里了,这里为了说明:可扩展添加 findByNameExact()方法 子类的附加方法。 泛型daoimpl :GenericDaoImpl, ID extends ...

    Java2核心技术.part3

    12.5.3保存对象引用问题的解决 12.5.4理解对象引用的输出格式 12.5.5修改默认的序列化机制 12.5.6单元素与类型安全枚举的序列化 12.5.7版本 12.5.8使用序列化进行克隆 12.6文件管理 12.7新的I...

    Java2核心技术.part1

    12.5.3保存对象引用问题的解决 12.5.4理解对象引用的输出格式 12.5.5修改默认的序列化机制 12.5.6单元素与类型安全枚举的序列化 12.5.7版本 12.5.8使用序列化进行克隆 12.6文件管理 12.7新的I/O ...

    Java2核心技术.part6

    12.5.3保存对象引用问题的解决 12.5.4理解对象引用的输出格式 12.5.5修改默认的序列化机制 12.5.6单元素与类型安全枚举的序列化 12.5.7版本 12.5.8使用序列化进行克隆 12.6文件管理 12.7新的I...

Global site tag (gtag.js) - Google Analytics