ORM框架类型自动转换原理

来源:互联网 发布:网络摄像监控 编辑:程序博客网 时间:2024/06/06 11:47
     我们在使用ORM框架时,从数据库中查询数据,然后返回一个集合或者其他类型。但是,框架怎么知道我要获取的是什么类型的呢?比如:List<Date>、Map<String,Integer>等,框架怎么知道我要返回的集合中的元素类型是Date、String、Integer呢?可能你会说是使用反射的方式,话是不错,但说反射毕竟太笼统了。我们可以从Hibernate框架的源码中获取点经验,既然Hibernate可以实现自动类型转换,那我们为何不向前辈学习呢?! 自动类型转换的方法大致如下:public class TestGer {public static void main(String[] args) throws NoSuchMethodException, SecurityException {Method method = TestGer.class.getMethod("test", List.class); //获取方法实例Type[] types = method.getGenericParameterTypes(); //获得原始类型参数ParameterizedType pt = (ParameterizedType) types[0];//获得的原始类型参数的是一个type类型的数组,数组的长度为实际方法参数的个数System.out.println(pt.getActualTypeArguments()[0]);//打印实际类型参数System.out.println(pt.getRawType());//打印原始类型System.out.println("-------------------------");Method method2 = TestGer.class.getMethod("testMap", Map.class);Type[] types2 = method2.getGenericParameterTypes();ParameterizedType pt2 = (ParameterizedType) types2[0];Type[] tps2 = pt2.getActualTypeArguments(); //实际类型参数长度为2,map包括key和valueSystem.out.println(tps2[0]); //map的key类型System.out.println(tps2[1]);//map的value类型System.out.println(pt2.getRawType()); //map的原始类型}public  void test(List<Date> date){}public void testMap(Map<String,Integer> map){}}关键点:上面的方式是通过方法的类型参数获取实际参数的类型的,换句话说也就是:我们不能通过如下方式获取实际参数的类型。                List<Date> date = new ArrayList<Date>();TypeVariable<?>[] clazz = date.getClass().getTypeParameters();我们没办法直接通过字节码获得集合中的实际参数化的类型,编译器在编译成字节码后会去掉集合中参数化类型信息。eg:                List<Date> dList = new ArrayList<Date>();List<String> sList = new ArrayList<String>();System.out.println(dList.getClass() == sList.getClass());上面的返回值是true,因为编译器把源代码编译成字节码时已经去掉了参数化的类型信息。 以我目前所知道的,我们只能通过方法签名获取集合中实际参数类型。Method类API中提供的有相关获取原始类型的方法,有兴趣的可以查阅。 Method API的getGenericParameterTypes()方法返回的是Type类型的数组,而Type有很多子类,比如大名鼎鼎的Class类也是Type的子类,也正如《Java编程思想》中所说type可以等同于class。而在这里我们需要用的是Type的子类ParameterizedType,ParameterizedType代表参数化的类型。我们可以通过其中的方法获取实际参数化的类型和原始类型。

0 0
原创粉丝点击