转载自:拈花微笑

自从Java 5引入泛型之后,Java与C++对于泛型不同的实现的优劣便一直是饭后的谈资。在我之前的很多training中,当讲到Java泛型时总是会和C++的实现比较,一般得出的结论是

  • Java使用类型擦除(type erasing),泛型信息只在编译时供javac作类型检查用,在编译后便被javac擦除,因此无法被反射
  • C++使用代码模板实现泛型,即在预处理时会生成类似「list_int」,「list_char」等的泛型类,虽然解决Java的运行时伪泛型的问题,但是会导致编译后的代码呈线性增长
  • 于是在一般情况下,Java的类型擦除实现较优

这三条已经比绝大多数的Java培训讲师讲得深刻了。但是如果下面有人问「在什么情况下C++的实现方式较优」时,除了无法被反射,我很难现抓一个有说服力的例子。今天,Spring的RestTemplate终于给了我这个例子

我遇到的问题如下(阅读需要有一些Spring MVC、REST基础)

有一个返回类型为List的MVC方法:

 Java |     copy code | ?  
1  
2
@RequestMapping(value = "...", method = RequestMethod.GET)
3
@ResponseBody
4
public List<DomainClass> doSomethingREST() {
5
    List<DomainClass> domainObjs = ... ;
6
    return domainObjs;
7
}
8  

在运行时,Spring MVC会将List转换成JSON字符串并返回至客户端。但是如果我在另一个service中使用RestTemplate直接调用该REST接口,问题便来了:

 Java |     copy code | ?  
1  
2
List<DomainClass> domainObjs = this.restTemplate.getForObject(this.restURL, List.class);
3  

关键在于第二个参数,是返回值的类型,RestTemplate会根据此类型选择适当的MessageConverter将调用REST接口的返回值反序列化为与类型匹配的对象。由于List的泛型参数在编译时被擦除,于是RestTemplate便无法确定List中的内容。「一般情况下」(REST接口返回值不是List类型)不会有问题,但是巧合的是,如果服务器端使用JSON对REST结果进行序列化,返回值会被封装在List中,此时,Spring已无法判断开发人员是想直接获得List封装的JSON内容还是需要更进一步使用Jackson库将JSON反序列化为Java对象。现实情况下,Spring选择的前者,于是便会抛出ClassCastException

上网搜了一圈,已经有人向Spring提交了enhancement请求(这里这里,其中第一个链接中的walkaround可以work),但是目前没有milestone

– EOF –

转:有关Java泛型的类型擦除(type erasing)的更多相关文章

  1. Java泛型:类型擦除

    类型擦除 代码片段一 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String& ...

  2. Java泛型之类型擦除

    类型擦除 学过C++模板的,在使用Java泛型的时候,会感觉到有点不疑问,例如:(1)无法定义一个泛型数组.无法调用泛型参数对象中对应的方法(当然,通过extends关键字是可以做到,只是比较麻烦): ...

  3. java 泛型的类型擦除与桥方法

    泛型类 --代码参考:java核心技术 卷1 第十版 public class Pair<T> { private T first; private T second; //构造器 pub ...

  4. java 泛型的类型擦除和桥方法

    oracle原文地址:https://docs.oracle.com/javase/tutorial/java/generics/erasure.html 在Java中,泛型的引入是为了在编译时提供强 ...

  5. Java泛型-类型擦除

    一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变 ...

  6. JAVA 泛型之类型擦除

    ★ 泛型是 JDK 1.5 版本引进的概念,之前是没有泛型的概念的,但泛型代码能够很好地和之前版本的代码很好地兼容. CollectionTest.java ---编译成CollectionTest. ...

  7. Java泛型的类型擦除

    package com.srie.testjava; import java.util.ArrayList; import java.util.List; public class TestGener ...

  8. Java泛型类与类型擦除

    转载自:http://blog.csdn.net/lonelyroamer/article/details/7868820 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型. ...

  9. java之集合类框架的简要知识点:泛型的类型擦除

    这里想说一下在集合框架前需要理解的小知识点,也是个人的肤浅理解,不知道理解的正不正确,请大家多多指教.这里必须谈一下java的泛型,因为它们联系紧密,我们先看一下这几行代码: Class c1 = n ...

随机推荐

  1. Android省电开发 浅析

    相信对于Android App省电的开发,一切性能优化都可以达到App的省电开发,所以一个省电的Android应用,性能优化占据很重要的位置.除此之外整理了几点关于Android应用省电的开发技巧. ...

  2. vijos P1375 大整数(高精不熟的一定要做!)

    /* 我尼玛这题不想说啥了 亏了高精写的熟..... 加减乘除max都写了 高精二分 */ #include<iostream> #include<cstdio> #inclu ...

  3. javabean、DTO、VO

    一.javabean 一. javabean 是什么? Bean的中文含义是“豆子”,顾名思义,JavaBean是指一段特殊的Java类, 就是有默然构造方法,只有get,set的方法的java类的对 ...

  4. EXCEL表格常用函数使用的难点

    1.  INDIRECT(ref_text,逻辑值) 返回由文本字符串指定的引用.此函数立即对引用进行计算,并显示其内容.ref_text,文本引用说明, (1) A1-样式的引用(逻辑值,T,缺省) ...

  5. dns-prefetch—DNS预解析技术

    今天在看一个网站的源代码时 发现了 <link rel="dns-prefetch" href="//static.tuweia.cn/"> 对dn ...

  6. PHP 注意问题

    一.表单  1,上传文件的表单使用post方式:还要加上enctype='multipart/form-data'.     2,一般要加上隐藏域:<input type=hidden name ...

  7. leetcode修炼之路——83. Remove Duplicates from Sorted List

    哈哈,我又来了.昨天发现题目太简单就没有放上来,今天来了一道有序链表的题.题目如下: Given a sorted linked list, delete all duplicates such th ...

  8. iOS开发UI篇——简单的浏览器查看程序

    一.程序实现要求 1.要求 2. 界面分析 (1) 需要读取或修改属性的控件需要设置属性 序号标签 图片 图片描述 左边按钮 右边按钮 (2) 需要监听响应事件的对象,需要添加监听方法 左边按钮 右边 ...

  9. eclipse中如何导入jar包

    如图,首先右键点击项目,选择最下面的properties, 然后进去之后点击java build path,右边会出来4个选项卡,选择libraries, 这时候最右边会有多个选项,第一个add ja ...

  10. 用soaplib的django webserver

    前面写过怎么利用suds来调用webservicePython调用基于https协议的SOAP WebService,这篇讲的是如何用soaplib开发SOAP WebService(最近发现国外开源 ...