转:有关Java泛型的类型擦除(type erasing)
转载自:拈花微笑
自从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)的更多相关文章
- Java泛型:类型擦除
类型擦除 代码片段一 Class c1 = new ArrayList<Integer>().getClass(); Class c2 = new ArrayList<String& ...
- Java泛型之类型擦除
类型擦除 学过C++模板的,在使用Java泛型的时候,会感觉到有点不疑问,例如:(1)无法定义一个泛型数组.无法调用泛型参数对象中对应的方法(当然,通过extends关键字是可以做到,只是比较麻烦): ...
- java 泛型的类型擦除与桥方法
泛型类 --代码参考:java核心技术 卷1 第十版 public class Pair<T> { private T first; private T second; //构造器 pub ...
- java 泛型的类型擦除和桥方法
oracle原文地址:https://docs.oracle.com/javase/tutorial/java/generics/erasure.html 在Java中,泛型的引入是为了在编译时提供强 ...
- Java泛型-类型擦除
一.概述 Java泛型在使用过程有诸多的问题,如不存在List<String>.class, List<Integer>不能赋值给List<Number>(不可协变 ...
- JAVA 泛型之类型擦除
★ 泛型是 JDK 1.5 版本引进的概念,之前是没有泛型的概念的,但泛型代码能够很好地和之前版本的代码很好地兼容. CollectionTest.java ---编译成CollectionTest. ...
- Java泛型的类型擦除
package com.srie.testjava; import java.util.ArrayList; import java.util.List; public class TestGener ...
- Java泛型类与类型擦除
转载自:http://blog.csdn.net/lonelyroamer/article/details/7868820 一.Java泛型的实现方法:类型擦除 前面已经说了,Java的泛型是伪泛型. ...
- java之集合类框架的简要知识点:泛型的类型擦除
这里想说一下在集合框架前需要理解的小知识点,也是个人的肤浅理解,不知道理解的正不正确,请大家多多指教.这里必须谈一下java的泛型,因为它们联系紧密,我们先看一下这几行代码: Class c1 = n ...
随机推荐
- codevs2034 01串2
/* 一开始认为是个水题 直接模拟 没想到只得了50分 一看数据吓niao了 模拟妥妥的TLE 实在不好优化了0.0(最快O(m)) 然后借鉴别人的 DP+神奇的输出 DP:状态:f[i][j] 前i ...
- python栈的实现(入栈,出栈)
#coding=utf-8 class Stack(): def __init__(st,size):#栈的初始化 st.stack=[]; st.size=size; st.top=-1 def p ...
- INSTALL_PARSE_FAILED_MANIFEST_MALFORMED 错误
在eclipse编译好文件之后,往AVD中安装apk,报错如下:INSTALL_PARSE_FAILED_MANIFEST_MALFORMED一般来说只需要检查AndroidManifest.xml中 ...
- 关于PHP导入项目的时候导入不了的情况
导入的时候,会发现明明是一个手动创建的一个项目, 才能导入, 有时候会发现这样导入不了的情况 那是因为,可能这个项目是手动创建的,如果通过IDE可能看不出来 不过如果你进入项目的根目录的时候就会知道 ...
- java中对象的转型
1.对象的向上转型——将子类的对象赋值给父类的引用 Student s=new Student(); Person p=s; 一个引用能够调哪些成员(变量和函数),取决于这个引用的类型 也就是Pe ...
- 深入理解offsetTop与offsetLeft
做为走上前端不归路的我,以前只是认为offsetTop是元素的左边框至包含元素offsetParent的左内边框之间的像素距离,同理offsetRight是相对于上内边框.那么问题来了,包含元素off ...
- apple
you are the apple of my eye
- Q我音乐
- php中session的运行机制
在PHP中session默认是以文件的形式存储于服务器的 而客户端和服务端则是通过session_id来完成握手的,默认情况下PHP会将session_id存储于cookie中,用户每次请求时该ses ...
- winform 剔除空格与换行显示
string strTeachingPlan = this.txtTeachingPlan.Text.ToString().Trim(); string[] maarr = strTeachingP ...