lotusswan

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  11 Posts :: 0 Stories :: 4 Comments :: 0 Trackbacks

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

public   static   void  wrongConversion()  {
        List
< Integer >  list  =   new  LinkedList < Integer >
();
        list.add(
1
);
        list.add(
2
);
        list.add(
3
);
        
        
//
下面的代码无法编译通过。
        
// List<Number> wrongList = list;

        
    }

    
    
public   static   void  rightConversion()  {
        LinkedList
< Integer >  list  =   new  LinkedList < Integer >
();
        list.add(
10
);
        list.add(
20
);
        list.add(
30
);
        
        List
< Integer >  rightList  =
 list;
        
for ( int  number: rightList) 
{
            System.out.println(number);
        }

        
    }

如果你运行上面的代码,你会发现前一个函数根本无法通过编译,而后一个函数不仅编译成功,而且能得到正确结果。这似乎给出了一个结论:对象的类型由集合类型来决定,对对象进行类型转换时也是对集合类型进行转换。事实确实如此!那么为什么会如此呢?
我们可以回忆一下以前我们对参数类型的描述:参数类型不过是一个占位符而已,在编译时,它会被具体的类型代替,同时对添加到集合对象中的数据进行参数检查;如果添加到对象中的数据类型不是指定的具体类型或其子类型,则编译出错;而且,编译以后,该占位符会被移除,运行时你是无法得到任何集合类型中数据的类型信息的。简而言之:
         List<String> strings = new LinkedList<String>( );
         List<Integer> ints = new LinkedList<Integer>( );
上面的代码在运行时和
         List strings = new LinkedList( );
         List ints = new LinkedList( );
毫无二致。了解了这一点以后,相信我们对于类型转换也会有更深的理解了。
泛型给我们带来了好处,使我们在编译时就能发现很多错误;然而任何事物都是柄双刃剑,泛型也不例外。泛型的缺点最明显之处就在于类型转换。如果你读过前面的文章,肯定看到过不带参数类型的集合对象转换为带参数类型的集合对象,其实不仅仅如此,这两者之间可以任意转换。这就意味着一点,我们不仅可以对集合类型进行转换,也可以对参数类型进行任意的转换。这似乎与前面的描述不符,因为上面的代码中的List<Number> wrongList = list;根本无法编译通过。确实如此,这行代码确实无法编译通过,不过我们中间做一步处理以后,上面的转换就可以正常编译了:
        List mediaList = list;
        List<Number> wrongList = mediaList;
由此可见,泛型在给我们带来好处的同时,也带来了无数陷阱,我们在编程时需十分注意,而Java的泛型机制也需要不断更新。
最后和以往一样,以一个拙劣的程序结束本文:
package  com.jiang.tiger.chap1;

import
 java.util.ArrayList;
import
 java.util.LinkedList;
import
 java.util.List;

public   class  GenericReflection 
{
    
private   static  List < Integer >  ints  =   new  ArrayList < Integer >
( );
    
    
public   static   void  fillList(List < Integer >  list) 
{
        
for  (Integer i : list) 
{
          ints.add(i);
        }

    }

    
    
public   static   void  printList( )  {
        
for  (Integer i : ints) 
{
            System.out.println(i);
        }

    }

    
    
public   static   void  badConversion()  {
        List
< Integer >  list  =   new  LinkedList < Integer >
();
        list.add(
1
);
        list.add(
2
);
        list.add(
3
);
        fillList(list);
        printList();
        List badList 
=
 list;
        badList.add(
" bad number "
);
        badList.add(
" wrong idea "
);
        fillList(list);
        printList();
        
    }

    
    
public   static   void  badConversion2()  {
        List list 
=   new
 LinkedList();
        list.add(
1
);
        list.add(
2
);
        list.add(
" bad number "
);
        
        List
< Integer >  badList  =
 list;
        badList.add(
12
);
        
for  (Integer i : badList) 
{
            System.out.println(i);
        }

    }

    
    
public   static   void  wrongConversion()  {
        List
< Integer >  list  =   new  LinkedList < Integer >
();
        list.add(
100
);
        list.add(
200
);
        list.add(
300
);
        
        
//
下面的代码无法编译通过。
        
// List<Number> wrongList = list;

        List mediaList  =  list;
        List
< Number >  wrongList  =
 mediaList;
        wrongList.add(
120.23
);
        wrongList.add(
0.1230
);
        
for (Integer inter : list) 
{
            System.out.println(inter);
        }

        
    }

    
    
public   static   void  rightConversion()  {
        LinkedList
< Integer >  list  =   new  LinkedList < Integer >
();
        list.add(
10
);
        list.add(
20
);
        list.add(
30
);
        
        List
< Integer >  rightList  =
 list;
        
for (Integer number: rightList) 
{
            System.out.println(number);
        }

        
    }

    
    
public   static   void  badReflection()  {
        List
< Integer >  myInts  =   new  ArrayList < Integer >
( );
        
        myInts.add(
4
);
        myInts.add(
5
);
        myInts.add(
6
);    
        
        System.out.println(
" Filling list and printing in normal way "
);
        fillList(myInts);
        printList( );
        
        
try  
{
            List list 
=  (List)GenericReflection. class .getDeclaredField( " ints " ).get( null
);
            list.add(
" Illegal Value! "
);
        }
  catch  (Exception e)  {
            e.printStackTrace( );
        }

        System.out.println(
" Printing with illegal values in list " );
        printList( );
    }

    
    
public   static   void  main(String[] args)  {
        
        System.out.println(
" rightConversion "
);
        rightConversion();
        
try
{
            Thread.sleep(
1000
);
            System.out.println(
" badConversion "
);
            badConversion();
        }
  catch (Exception ce)  {
            ce.printStackTrace();
        }

        
try {
            Thread.sleep(
1000
);
            System.out.println(
" badConversion2 "
);
            badConversion2();
        }
  catch (Exception ce)  {
            ce.printStackTrace();
        }

        
try {
            Thread.sleep(
1000
);
            System.out.println(
" wrongConversion "
);
            wrongConversion();
        }
  catch (Exception ce)  {
            ce.printStackTrace();
        }

        
try {
            Thread.sleep(
1000
);
            System.out.println(
" badReflection "
);
            badReflection();
        }
  catch (Exception ce)  {
            ce.printStackTrace();
        }

        
    }

}
上面程序的输出结果为:
rightConversion
10
20
30
badConversion
1
2
3
java.lang.ClassCastException: java.lang.String
    at com.jiang.tiger.chap1.GenericReflection.fillList(GenericReflection.java:11)
    at com.jiang.tiger.chap1.GenericReflection.badConversion(GenericReflection.java:32)
    at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:109)
badConversion2
1
2
java.lang.ClassCastException: java.lang.String
    at com.jiang.tiger.chap1.GenericReflection.badConversion2(GenericReflection.java:45)
    at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:116)
wrongConversion
100
200
300
java.lang.ClassCastException: java.lang.Double
    at com.jiang.tiger.chap1.GenericReflection.wrongConversion(GenericReflection.java:62)
    at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:123)
badReflection
Filling list and printing in normal way
1
2
3
1
2
3
4
5
6
java.lang.ClassCastException: java.lang.String
    at com.jiang.tiger.chap1.GenericReflection.printList(GenericReflection.java:17)
    at com.jiang.tiger.chap1.GenericReflection.badReflection(GenericReflection.java:99)Printing with illegal values in list
1
2
3
1
2
3
4
5
6

    at com.jiang.tiger.chap1.GenericReflection.main(GenericReflection.java:130)
posted on 2006-12-06 22:53 lotusswan 阅读(3111) 评论(0)  编辑  收藏 所属分类: Tiger学习笔记

只有注册用户登录后才能发表评论。


网站导航: