论坛首页 Java企业应用论坛

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

浏览 7272 次
精华帖 (0) :: 良好帖 (1) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-05-22  
最近在开发中遇到一个现象,就是在编译时整个代码中使用了泛型,并没有出现任何类型转换上的问题。代码如下:
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的引入泛型后的彻底类库大翻新,到底是利大于弊,还是弊大于利呢?
   发表时间:2011-05-23  
个人认为泛型的引入是一个弊大于利的举措,首先jdk5所有类库进行了一次全面翻新,使java语言的语法看上去复杂了很多;其次,仅仅能保证编译时的类型转换正确,实际上意义不大,目前高并发的程序,全都在使用分布式缓存;最后,泛型的引入,感觉上对程序的健壮性造成了冲击,表面上看使类型转换的问题泛型化,但是泛型方法等一系列的引入,给广大程序员造成了困惑,这真是一个非常健壮的语法规范/格式么?
0 请登录后投票
   发表时间:2011-05-23  
<String>就比(String)困惑了?
0 请登录后投票
   发表时间:2011-05-23  
gtssgtss 写道
<String>就比(String)困惑了?

我主要指泛型方法这类东西
0 请登录后投票
   发表时间:2011-05-23   最后修改:2011-05-23
即使你用原来的方式写
void foo(List<ADto> res) {   
        if(res != null) {   
            List resIds = new ArrayList();   
            for (Iterator iterator = resIds.iterator(); iterator.hasNext();) {
                ADto a = (ADto) iterator.next();//在这一行报java.lang.ClassCastException   
                resIds.add(a.getId());
                
            }
        }          
           
        //do sth   
        }  


由于使用分布式缓存,难道在运行时就不报java.lang.ClassCastException了吗?
泛型这个东西只是语法糖,但至少还提供了一个编译时检查
0 请登录后投票
   发表时间:2011-05-23  
leon_a 写道
即使你用原来的方式写
void foo(List<ADto> res) {   
        if(res != null) {   
            List resIds = new ArrayList();   
            for (Iterator iterator = resIds.iterator(); iterator.hasNext();) {
                ADto a = (ADto) iterator.next();//在这一行报java.lang.ClassCastException   
                resIds.add(a.getId());
                
            }
        }          
           
        //do sth   
        }  


由于使用分布式缓存,难道在运行时就不报java.lang.ClassCastException了吗?
泛型这个东西只是语法糖,但至少还提供了一个编译时检查

0 请登录后投票
   发表时间:2011-05-23  
LZ喜欢强转?
0 请登录后投票
   发表时间:2011-05-23  
lz举例不当,你强转一样报错。
0 请登录后投票
   发表时间:2011-05-23  
ironsabre 写道
lz举例不当,你强转一样报错。

问题是强转报错很容易看出来,用泛型之后,很多人会觉得那一行不应该出错。。。
但实际只是个编译时约束
0 请登录后投票
   发表时间:2011-05-23  
有可能 是在不同的classLoader 中完成 写入  和  读出的
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics