`
sharong
  • 浏览: 493443 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
D1667ae2-8cfc-3b68-ac7c-5e282789fa4a
论开源
浏览量:8720
7eb53364-fe48-371c-9623-887640be0185
Spring-data-j...
浏览量:13059
社区版块
存档分类
最新评论

好还是坏-JDK5对泛型的引入

阅读更多
最近在开发中遇到一个现象,就是在编译时整个代码中使用了泛型,并没有出现任何类型转换上的问题。代码如下:
void foo(List<ADto> res) {
	if(res != null) {
		List<Integer> resIds = new ArrayList<Integer>();
	        for (ADto a : res) {//在这一行报java.lang.ClassCastException
        	    resIds.add(a.getId());
	        }
	}    	
	
	//do sth
    }

然而程序在运行时,总是在for循环处报java.lang.ClassCastException,也就是类型转换异常。根据Java的语义来讲,这是一个不应该发生的错误异常。

因为这是一个高并发程序,使用了Memcached等缓存,所以根据经验,很容易能够判断出来,无论如何,res都是从缓存中取出来的旧的集合数据,而非其他可能。幸好我还记得几天前的代码中的res中放置的是其他类型的数据。so,开始清除缓存,之后再也未出现ClassCastException这个异常报错了。

通过这个案例,使我们认识到,泛型仅仅是JDK5之后引入的一个编译时级别上的判断和支持。进入运行时,如果方法中传入的实参并未遵循泛型的约束,程序默认不会报错,只有运行到实际类型转换时,才会抛出或者捕获这个异常,然后导致程序在运行时失败。由于泛型仅仅是编译时级别上的支持,就非常容易在程序运行时造成更大的困惑。

从这个层面来看,泛型的引入,并未很好的解决java运行时所带来的类型转换问题,或者说,泛型的引入,并不是为了解决整个程序从编译时到运行时的全部类型转换的问题,泛型仅仅是为了解决编译时的类型转换而生。那么这样的做法,对于java从1.4版就已经比较成型的语言,到jdk5的引入泛型后的彻底类库大翻新,到底是利大于弊,还是弊大于利呢?
分享到:
评论
25 楼 ak_2005 2011-05-24  
LZ对泛型还理解不到位。。。
24 楼 imacback 2011-05-24  
存在即合理,泛型还是有好多好处的, 这个例子本身不能说明问题

ps:我们不能根据某个问题就得出一个定论:)
23 楼 mercyblitz 2011-05-24  
哥们,你的代码有问题,即使是强制转型也会报错的。远程方法调用时,或者反射调用是,Class文件中是没有泛型的特征的。
22 楼 captmjc 2011-05-24  
那是因为lz调用了foo(List)而不是foo(List<ADto>)吧,这个会编译警告的,你选择忽略这个警告,就不能怪别人了。
21 楼 cosmo1987 2011-05-24  
java的泛型怎么说呢...觉得还是比不上C++的功能吧,使用了泛型之后,类型擦拭后的对象还是不能在运行时自动确定对象类型。如果可以进步到在运行时确定类型,并能即时调用类型中的方法的话,就真的如了泛型,这个名字的意义:实现广泛的类型
20 楼 ahaqi110 2011-05-24  
此错误与泛型无关。JDK5引入泛型 不用怀疑 一定是进步的。我觉得用了泛型让编程变的更简单了,让我们看程序一目了然,并不像楼主说的那么复杂。
19 楼 chenenbang 2011-05-24  
这个题目太大了,看这个例子,我觉得不能说明问题!
18 楼 yizhilong28 2011-05-24  
sharong 写道
ironsabre 写道
lz举例不当,你强转一样报错。

问题是强转报错很容易看出来,用泛型之后,很多人会觉得那一行不应该出错。。。
但实际只是个编译时约束

泛型的引入是一种进步,这点不需要质疑。
出现lz所说的情形,只能说写程序的人本身没搞清楚状况,如同空指针一样。
17 楼 advantech 2011-05-24  
这个错误分析不出来,我觉得还是回家种红薯吧,还做什么程序员。
16 楼 useryouyou 2011-05-23  
jdk 5 出了 泛型 ,数组用的就比较少了。
15 楼 zean 2011-05-23  
jdk确实越来复杂,1.4的功能已经差不多了,我觉得java应该把主要精力放在开发工具上,比起微软的开发工具相差还挺远,老折腾语言层,难道又要整一个C++出来?
14 楼 chunquedong 2011-05-23  
这个真不好说。但增加的复杂性很明显,什么协变逆变的。
13 楼 ironsabre 2011-05-23  
sharong 写道
ironsabre 写道
lz举例不当,你强转一样报错。

问题是强转报错很容易看出来,用泛型之后,很多人会觉得那一行不应该出错。。。
但实际只是个编译时约束


那么明显的的报错你看不出来?
12 楼 xijieqjx 2011-05-23  
类型擦除就相当于把强制类型转换的代码用编译器实现了。代码规范了一些。但对我来说确实不好理解,感觉不是泛型,是一层强制转换披了张泛型的皮。
11 楼 nobody2008 2011-05-23  
题目大了!


再说,java.lang.ClassCastException是运行时异常,也就是说是你自己把代码写错了,与泛型无关。
10 楼 KimHo 2011-05-23  
sharong 写道
ironsabre 写道
lz举例不当,你强转一样报错。

问题是强转报错很容易看出来,用泛型之后,很多人会觉得那一行不应该出错。。。
但实际只是个编译时约束

也只能是个编译时约束
难道jdk能智能到知道你代码实际运行的所有可能情况?(超前预知?)
9 楼 jackerxff 2011-05-23  
有可能 是在不同的classLoader 中完成 写入  和  读出的
8 楼 sharong 2011-05-23  
ironsabre 写道
lz举例不当,你强转一样报错。

问题是强转报错很容易看出来,用泛型之后,很多人会觉得那一行不应该出错。。。
但实际只是个编译时约束
7 楼 ironsabre 2011-05-23  
lz举例不当,你强转一样报错。
6 楼 skycray 2011-05-23  
LZ喜欢强转?

相关推荐

    java经典教程-JDK1.5的泛型实现

    Java泛型是自JDK 1.5版本引入的一项重要特性,它极大地提高了代码的类型安全性和重用性。在本教程中,我们将深入探讨Java泛型的实现及其在实际编程中的应用。 泛型允许我们在类、接口和方法中定义类型参数,这样就...

    guava-jdk5

    《Guava-JDK5:Java开发者的高效工具库》 Guava是Google为Java平台推出的一个开源库,它集合了许多实用的功能,极大地提高了Java开发的效率。Guava-JDK5是Guava的一个版本,专为支持Java 5的环境而设计。这个版本...

    jdk5.zip_java 泛型_jdk5 泛型_泛型

    Java 泛型是Java编程语言中的一个重要特性,它在JDK 5版本中引入,显著提高了代码的类型安全性和重用性。泛型允许程序员在类、接口和方法中使用类型参数,使得容器(如ArrayList、LinkedList等)可以保存特定类型的...

    java-jdk1.8-jdk-8u151-linux-x64.zip

    - **类型推断增强**:编译器能更好地推断泛型的类型,使得代码更加简洁。 - **Stream API**:提供了一种处理集合的新方式,可以进行过滤、映射、归约等操作,极大地提高了代码的可读性。 - **Date和Time API的改进...

    java-jdk1.8-jdk-8u181-linux-x64.zip

    - ** Date和Time API**:对日期和时间处理进行了全面的改进,引入了新的java.time包,取代了旧的java.util.Date和java.util.Calendar。 - ** Method References**:允许直接引用类或对象的方法,作为函数接口的实现...

    jdk1.5的泛型实现

    Java编程的泛型是JDK 1.5版本引入的一项重要特性,极大地提高了代码的类型安全性和重用性。泛型允许我们在定义类、接口和方法时声明参数化类型,这样在编译时期就能捕获类型错误,而不是等到运行时。这种特性在面向...

    Jdk15泛型的实现

    JDK1.5引入的泛型技术极大地增强了Java语言的灵活性和安全性,通过参数化类型、泛型类和泛型算法,开发者可以编写更加通用且类型安全的代码。理解和熟练掌握泛型的使用,对于提高Java开发者的编程技能和软件质量有着...

    java-jdk1.8-jdk-8u151-windows-x64.zip

    6. **类型推断增强**:编译器可以更好地推断泛型的类型,使代码更简洁。 7. **Nashorn JavaScript引擎**:内置的JavaScript引擎允许Java代码与JavaScript交互,增加了语言间集成的能力。 安装"jdk-8u151-windows-x...

    bit-jdk-8u5-windows-i586.rar

    标题中的"bit-jdk-8u5-windows-i586.rar"指出这是一个适用于32位Windows系统的JDK 1.8的早期版本,具体为更新5(Update 5)。这个压缩包是Java环境部署的关键,对于任何想要在Windows平台上进行Java开发的用户来说,...

    java-jdk1.8-jdk-8u171-linux-x64.zip

    5. 验证JDK是否安装成功,输入`java -version`,如果显示正确版本号,说明安装完成。 参考教程链接可能会提供更详细的安装指导,包括如何处理依赖问题、解决权限问题以及设置系统级默认JDK等。 总之,Java JDK 1.8...

    JDK1.5的泛型实现.zip

    总之,JDK 1.5的泛型引入增强了Java的类型系统,提升了代码的清晰度和安全性。通过类型参数、类型擦除、通配符和边界等机制,泛型使得开发者能够在编译时检测类型错误,从而降低了运行时出错的可能性。在实际编程中...

    java-jdk1.7-jdk-7u80-windows-x64.zip

    总之,Java JDK 1.7是Java开发不可或缺的一部分,其新特性和优化对提升开发效率和程序性能有显著作用。无论是初学者还是经验丰富的开发者,都需要掌握这一版本的使用,以便更好地利用Java的强大功能。

    jdk1.6--jdk-6u45-windows-i586.exe.zip

    7. **NIO.2**:Java 6引入了新的I/O API,提供了更好的异步I/O操作和文件系统访问。 8. **改进的JDBC**:对JDBC API进行了增强,如新增了Statement的executeUpdate(String sql, int autoGeneratedKeys)方法,支持...

    jdk1.7--jdk-7u15-windows-i586.zip

    5. **NIO.2**:引入了新的文件系统API,增加了对异步I/O的支持,以及更好的文件路径处理和文件观察者功能。 6. **Type Inference for Generic Instance Creation**:类型推断的改进,使得创建泛型实例更加简洁。 7...

    jdk1.7 java官网正式版Windows 64位-jdk-7u80-windows-x64.exe

    首先,JDK 1.7在类型推断方面引入了"钻石操作符"(),使得在创建泛型实例时可以省略类型参数,提高了代码的简洁性。例如,`List&lt;String&gt; list = new ArrayList();` 这样的写法在JDK 1.7中被广泛接受。 其次,JDK ...

    java-jdk1.8-jdk-8u172-windows-x64.zip

    在Java开发中,JDK 1.8引入了一些重要的特性,如Lambda表达式、方法引用、类型推断(通过`&lt;&gt;`操作符实现的泛型实例化)、默认方法(在接口中定义的具有实现的方法)以及改进的日期时间API。这些特性极大地提高了代码...

    JDK1.4.2-JDK1.6-JDK1.7-JDK1.8 中文帮助文档

    JDK1.4.2是Java发展历程中的一个重要里程碑,其中引入了一些关键特性: 1. **NIO(New Input/Output)**:提供了一种非阻塞I/O模型,允许程序在处理多个输入/输出流时提高效率,特别适用于网络和大文件操作。 2. *...

    Java 基础(4-8) - 泛型机制详解.pdf

    Java泛型是自JDK 1.5版本引入的一个重要特性,目的是为了提高代码的类型安全性和重用性。在Java中,泛型允许开发者在类、接口和方法中使用类型参数,使得代码能处理多种数据类型而无需重复编写相似的代码。然而,...

    Linux-x64-jdk-1.8

    另外,Java 8还改进了反射API,增加了对泛型的支持,使得在运行时可以获取到关于泛型类型的信息。同时,Optional类的引入是为了防止空指针异常,它提供了一种安全的方式来处理可能为空的对象引用。 在JDK安装过程中...

    《精通JAVA----JDK》

    12. **泛型**:泛型引入了类型参数的概念,增强了代码的类型安全,减少了强制类型转换,提升了代码的复用性。 13. **模块系统(Java 9+)**:Java 9引入了模块系统,使得大型项目可以更好地组织和管理依赖关系,...

Global site tag (gtag.js) - Google Analytics