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 閱讀(3124) 評論(0)  編輯  收藏 所屬分類: Tiger學習筆記
          主站蜘蛛池模板: 渝北区| 安义县| 伊川县| 门源| 抚远县| 博白县| 长沙县| 青铜峡市| 泸西县| 墨江| 越西县| 梅河口市| 清涧县| 阳朔县| 和林格尔县| 南汇区| 小金县| 南康市| 纳雍县| 海淀区| 安阳县| 昭平县| 新闻| 周口市| 彭州市| 卢龙县| 鸡西市| 阳信县| 英德市| 台山市| 徐闻县| 临沂市| 潢川县| 新郑市| 商水县| 永年县| 九龙县| 缙云县| 金平| 什邡市| 抚远县|