`
欣仔91
  • 浏览: 1519 次
  • 性别: 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 泛型方法使用示例

    下面我们将深入探讨Java泛型方法的概念、语法以及使用示例。 **一、泛型方法概念** 泛型方法是一种具有类型参数的方法,这些类型参数可以在方法声明时指定,并在方法体内部使用。与类的泛型类似,它们提供了编译时...

    泛型 反射 相关概念方法使用

    泛型是Java 5引入的一项特性,它允许在定义类、接口和方法时指定类型参数,以增强代码的类型安全性和可读性。通过使用泛型,我们可以限制容器(如集合)中存储的元素类型,避免在运行时进行强制类型转换,并减少潜在...

    java * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class

    提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,java * 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class,java * 反射工具类. 提供调用getter/...

    java 基于泛型与反射的通用 DAO

    // 使用反射调用SQL插入方法 Method saveMethod = getMethod("executeInsert", Users.class); saveMethod.invoke(jdbcTemplate, user); } // 获取并执行SQL查询方法 private Method getMethod(String method...

    JAVA5泛型和反射

    泛型主要是为了解决在编程中频繁进行类型转换的问题,而反射则允许程序在运行时动态地获取类的信息和调用方法。 泛型类型: 在 Java 5 之前,像 `Hashtable` 这样的集合类只能存储 `Object` 类型的数据,这意味着在...

    Java泛型总结(2)进阶篇

    综上所述,Java泛型的进阶使用涉及多个方面,包括通配符、边界、类型擦除、泛型方法等,这些都对编写高效、安全的代码有着重要作用。理解并熟练掌握这些概念,将有助于提高Java开发的效率和质量。在实际开发中,我们...

    Java反射泛型,实现数据库的动态增删改查等功能

    例如,我们可以创建一个`DatabaseExecutor`类,它接受SQL语句作为输入,并通过反射调用`Statement`或`PreparedStatement`对象的`executeUpdate`或`executeQuery`方法。这样,只需改变传入的SQL字符串,就可以执行...

    Java泛型类型擦除后的补偿

    总结来说,Java泛型的类型擦除虽然在运行时消除了类型信息,但通过编译时的类型检查、桥接方法、通配符等补偿机制,仍然实现了强大的类型安全和便利性。开发者应理解这些补偿机制,以便更好地利用Java泛型进行类型...

    Java基础入门四泛型反射注解.pdf

    泛型是Java SE 5版本引入的一个新特性,它的主要目的是允许在使用类、接口和方法时能够引用到任何类型的对象,同时在编译期间就能进行类型检查,提供更安全的代码。泛型类和泛型方法可以提高代码的复用性,并减少...

    Java泛型实例

    - Java泛型在编译后会被类型擦除,即所有的类型参数都会被替换为其边界类型(通常为 `Object`),因此泛型不适用于运行时的反射操作。 - 尽管类型参数在运行时不存在,但在编译期间,泛型提供了类型检查,确保了...

    java 泛型

    这些桥接方法是类型安全的,允许在无泛型的旧代码中调用泛型方法。 10. **反射和泛型**:虽然泛型信息在运行时被擦除,但通过反射可以获取到泛型的原始类型信息,这对于编写一些高级的库和工具非常有用。 通过理解...

    Java泛型和反射.ppt

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

    重新理解Java泛型

    Java泛型是Java编程语言中的一个重要特性,它允许在类、接口和方法中使用类型参数,从而提高了代码的类型安全性和可复用性。本文旨在深入解析Java泛型的各个方面,帮助开发者形成全面、清晰的理解。 1. **泛型基础*...

    myreflect.rar 反射和泛型使用源码

    Java编程语言中的反射和泛型是两个非常重要的概念,它们为开发者提供了强大的工具来操作类、接口、对象以及参数类型。在"myreflect.rar"这个压缩包中,我们可以期待找到一系列关于这两个主题的源代码示例,这将有助...

    基于泛型反射的数据层封装+MSSQLJDBC3.0驱动

    在这个特定的案例中,"基于泛型反射的数据层封装"是利用了Java的泛型和反射特性来实现这一目标。泛型提供了一种在编译时类型安全的方式,允许我们创建可以处理多种类型的类、接口和方法。而反射则是Java提供的一种...

    java泛型学习全面页面下载资料

    Java泛型是Java编程语言中的一个关键特性,它在2004年随着Java SE 5.0的发布而引入,极大地增强了类型安全性和代码可读性。泛型允许我们在编写代码时指定容器(如集合)可以存储的数据类型,从而在编译阶段就能捕获...

    java反射与泛型综合例子

    Java反射是Java语言提供的一种能力,允许运行中的程序动态地获取类的信息(如类名、方法名、参数类型等)并调用这些方法。反射机制的核心类包括`Class`、`Constructor`、`Method`和`Field`,它们分别代表类、构造器...

    java 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class

    提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实...

    Java-Java反射与泛型教程

    Java泛型是自Java 5引入的一种类型安全机制,它允许在编译时检查类型,从而避免了类型转换异常。泛型主要应用于类、接口和方法。 1. **泛型类**: 定义泛型类时,可以使用尖括号来声明类型参数,如`class Container...

Global site tag (gtag.js) - Google Analytics