详解泛型与类型转换

开发 后端
Java 5.0引入泛型以后,提高了类型安全性,然而也给编程带来了新的挑战以及新的误区,类型转换就是一个很好的例子。

Java 5.0引入泛型以后,提高了类型安全性,然而也给编程带来了新的挑战以及新的误区,类型转换就是一个很好的例子。引入泛型以后,对象的类型似乎由两个类型构成:集合类型和参数类型,例如List list = new LinkedList(),似乎list的类型由List和Integer共同决定。如果真是这样,那么我们如果希望对list进行类型转换,我们该怎么办?是对List转换,还是对Integer转换?要解答上面的问题很简单,编写如下的代码,运行之就可看出端倪:

 

  1. public   static   void  wrongConversion()   {  
  2.         List < Integer >  list  =   new  LinkedList < Integer > ();  
  3.         list.add( 1 );  
  4.         list.add( 2 );  
  5.         list.add( 3 );  
  6.           
  7.          // 下面的代码无法编译通过。  
  8.          // List wrongList = list;   
  9.            
  10.     }   
  11.       
  12.      public   static   void  rightConversion()   {  
  13.         LinkedList < Integer >  list  =   new  LinkedList < Integer > ();  
  14.         list.add( 10 );  
  15.         list.add( 20 );  
  16.         list.add( 30 );  
  17.           
  18.         List < Integer >  rightList  =  list;  
  19.          for ( int  number: rightList)   {  
  20.             System.out.println(number);  
  21.         }   
  22.           
  23.     }  

 

如果你运行上面的代码,你会发现前一个函数根本无法通过编译,而后一个函数不仅编译成功,而且能得到正确结果。这似乎给出了一个结论:对象的类型由集合类型来决定,对对象进行类型转换时也是对集合类型进行转换。事实确实如此!那么为什么会如此呢?

我们可以回忆一下以前我们对参数类型的描述:参数类型不过是一个占位符而已,在编译时,它会被具体的类型代替,同时对添加到集合对象中的数据进行参数检查;如果添加到对象中的数据类型不是指定的具体类型或其子类型,则编译出错;而且,编译以后,该占位符会被移除,运行时你是无法得到任何集合类型中数据的类型信息的。简而言之:

List strings = new LinkedList( );

List ints = new LinkedList( );

上面的代码在运行时和

List strings = new LinkedList( );

List ints = new LinkedList( );

毫无二致。了解了这一点以后,相信我们对于类型转换也会有更深的理解了。

泛型给我们带来了好处,使我们在编译时就能发现很多错误;然而任何事物都是柄双刃剑,泛型也不例外。泛型的缺点最明显之处就在于类型转换。如果你读过前面的文章,肯定看到过不带参数类型的集合对象转换为带参数类型的集合对象,其实不仅仅如此,这两者之间可以任意转换。这就意味着一点,我们不仅可以对集合类型进行转换,也可以对参数类型进行任意的转换。这似乎与前面的描述不符,因为上面的代码中的List wrongList = list;根本无法编译通过。确实如此,这行代码确实无法编译通过,不过我们中间做一步处理以后,上面的转换就可以正常编译了:

List mediaList = list;

List wrongList = mediaList;

由此可见,泛型在给我们带来好处的同时,也带来了无数陷阱,我们在编程时需十分注意,而Java的泛型机制也需要不断更新。

最后和以往一样,以一个拙劣的程序结束本文:

上面程序的输出结果为:

 

  1. rightConversion  
  2. 10 
  3. 20 
  4. 30 
  5. badConversion  
  6. 1 
  7. 2 
  8. 3 
  9. java.lang.ClassCastException: java.lang.String  
  10.     at com.jiang.tiger.chap1.GenericReflection.fillList(GenericReflection.java:11)  
  11.     at com.jiang.tiger.chap1.GenericReflection.badConversion(GenericReflection.java:32)  
  12.     at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:109)  
  13. badConversion2  
  14. 1 
  15. 2 
  16. java.lang.ClassCastException: java.lang.String  
  17.     at com.jiang.tiger.chap1.GenericReflection.badConversion2(GenericReflection.java:45)  
  18.     at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:116)  
  19. wrongConversion  
  20. 100 
  21. 200 
  22. 300 
  23. java.lang.ClassCastException: java.lang.Double  
  24.     at com.jiang.tiger.chap1.GenericReflection.wrongConversion(GenericReflection.java:62)  
  25.     at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:123)  
  26. badReflection  
  27. Filling list and printing in normal way  
  28. 1 
  29. 2 
  30. 3 
  31. 1 
  32. 2 
  33. 3 
  34. 4 
  35. 5 
  36. 6 
  37. java.lang.ClassCastException: java.lang.String  
  38.     at com.jiang.tiger.chap1.GenericReflection.printList(GenericReflection.java:17)  
  39.     at com.jiang.tiger.chap1.GenericReflection.badReflection(GenericReflection.java:99)Printing with illegal values in list  
  40. 1 
  41. 2 
  42. 3 
  43. 1 
  44. 2 
  45. 3 
  46. 4 
  47. 5 
  48. 6 
  49.  
  50.     at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:130)  

【编辑推荐】

  1. Java泛型的理解与等价实现
  2. Java泛型编程快速入门
  3. 浅谈关于C#、Java泛型的看法
  4. 在Java中定义自己的工具库
  5. Java技术在协同软件中的应用
责任编辑:金贺 来源: ITEYE博客
相关推荐

2009-08-24 14:20:13

C# 强制类型转换

2010-01-20 18:22:37

VB.NET泛型类型

2021-06-18 08:25:42

Java泛型通配符

2024-10-28 00:40:49

Go语法版本

2009-08-24 13:52:04

C# 泛型约束

2023-03-24 15:53:24

JavaJava 泛型开发

2009-09-08 16:36:10

LINQ查询基于泛型类

2022-06-19 22:54:08

TypeScript泛型工具

2023-04-10 16:34:45

编程Java开发

2009-07-30 14:00:21

ASP.NET 2.0

2009-08-24 14:51:25

C# 泛型泛型类型

2009-04-24 09:33:12

LINQ查询非泛型

2021-06-17 06:51:32

Java泛型Java编程

2011-03-21 16:26:28

java泛型

2021-07-01 06:47:30

Java泛型泛型擦除

2024-10-22 16:59:07

2024-11-05 09:11:09

TypeScript开发者代码

2013-03-20 09:27:33

C#泛型

2009-08-24 18:22:05

C# 泛型编程

2021-07-09 06:11:37

Java泛型Object类型
点赞
收藏

51CTO技术栈公众号