lotusswan

            BlogJava :: 首頁 :: 聯(lián)系 :: 聚合  :: 管理
            11 Posts :: 0 Stories :: 4 Comments :: 0 Trackbacks

          Java的一個巨大優(yōu)勢是其類型安全性。在Java中,除了基本類型以外的所有事物都是一個對象,而且這個對象或顯示,或隱式地繼承自O(shè)bject類,這給Java帶來了巨大的類型安全性。任何方法的參數(shù)都必須具有某一特定類型,調(diào)用該方法時,給定的實參的類型要么是該類型本身,要么可以轉(zhuǎn)換(映射)為該類型,否則就會產(chǎn)生編譯時錯誤,這避免了很多類型不匹配帶來運行時錯誤的情況發(fā)生。然而,Java的類型安全性一直以來有一個嚴重的漏洞,這就是集合中的元素的數(shù)據(jù)類型。不信的話,看看下面的例子:

          package ?com.jiang.tiger.chap1;
          import
          ?java.util.ArrayList;
          import
          ?java.util.List;

          public ? class ?ListTester?
          {
          ????
          public ? static ? void ?safelessList()?
          {
          ????????List?list?
          = ? new
          ?ArrayList();
          ????????
          int ?number? = ? 1010
          ;
          ????????list.add(
          " good "
          );
          ????????list.add(
          " ok "
          );
          ????????list.add(
          " nice "
          );
          ????????list.add(number);
          ????????list.add(
          " wrong "
          );
          ????????
          int ?length? =
          ?list.size();
          ????????String?value?
          = ? null
          ;
          ????????
          ????????
          for ( int ?i? = ? 0 ;?i? < ?length;?i ++ )?
          {
          ????????????value?
          =
          ?(String)?list.get(i);
          ????????????System.out.println(value);
          ????????}

          ????}

          ????
          ????
          /**
          ?????*?
          @param ?args
          ?????
          */

          ????
          public ? static ? void ?main(String[]?args)? {
          ????????
          // ?TODO?自動生成方法存根

          ????????safelessList();
          ????}

          }

          在上例中,本來我是想得到一個字符串列表的,然而一不小心我加入了一個int類型的數(shù)據(jù),很可惜,由于Java 5.0以前的集合無法保證類型安全性,因此上面的代碼編譯正確,然而運行時就會出錯:

          good
          ok
          nice
          Exception?in?thread?
          " main "
          ?java.lang.ClassCastException:?java.lang.Integer
          ????at?com.jiang.tiger.chap1.ListTester.safelessList(ListTester.java:
          18
          )
          ????at?com.jiang.tiger.chap1.ListTester.main(ListTester.java:
          28
          )

          上面的代碼還有一個惱人的問題:每次我從List中獲得數(shù)據(jù)時,雖然我知道獲得的肯定是字符串,然而我每次仍然得進行一次映射將取得的數(shù)據(jù)轉(zhuǎn)換為字符串。沒辦法,誰讓List不是類型安全的呢,它壓根就不知道我往里面放置的是String,它唯一知道的就是它里面放置了很多Object。
          在Java 5.0中,這一漏洞已經(jīng)被完全堵上了,因為Java 5.0引入了泛型這一令人激動萬分的新特性。在Java 5.0中,我們可以指定List只能接受特定類型的數(shù)據(jù),而不是接受所有的Object。我們修改上面的例子,用List<String>替換掉List,編譯時就會出錯,我們就知道,我們往List中插入了不合適的數(shù)據(jù),我們就有可能在產(chǎn)品交付之前發(fā)現(xiàn)問題,而且惱人的映射也不需要了。在Java 5.0中,采用的是泛型技術(shù)來實現(xiàn)這些的。所謂泛型,如果初次結(jié)束,可以簡單地理解為一個占位符,放在那兒告訴別人,這個位置是有人(類型)的,你可以安排一個人(類型)過來。至于這個人(類型)是男是女(具體的類型),是高是矮無所謂,完全由你決定。那么這個人什么時候會來呢?答案就是你使用占位符的時候,他就會來,而且是由你指定的。
          可見,泛型不僅帶來了類型安全性,還給我們編程帶來了靈活性。唯一比較麻煩的是往List中插入基本類型數(shù)據(jù),由于為List指定類型只能是引用類型,因此無法給List指定基本類型。如果要用List存放基本類型數(shù)據(jù),必須指定該類型對應(yīng)的引用類型,例如下例:

          package ?com.jiang.tiger.chap1;
          import
          ?java.util.ArrayList;
          import
          ?java.util.List;

          public ? class ?ListTester?
          {
          ????
          public ? static ? void ?safefulList()?
          {
          ????????List
          < String > ?list? = ? new ?ArrayList < String >
          ();
          ????????
          int ?number? = ? 1010
          ;
          ????????list.add(
          " good "
          );
          ????????list.add(
          " ok "
          );
          ????????list.add(
          " nice "
          );
          ????????
          //
          下面注釋的代碼編譯會出錯
          ????????
          // list.add(number);

          ????????list.add( " wrong " );
          ????????
          int ?length? =
          ?list.size();
          ????????String?value?
          = ? null
          ;
          ????????
          ????????
          for ( int ?i? = ? 0 ;?i? < ?length;?i ++ )?
          {
          ????????????value?
          =
          ?list.get(i);
          ????????????System.out.println(value);
          ????????}

          ????}

          ????
          ????
          public ? static ? void ?intList()? {
          ????????
          //
          給List指定類型只能是引用類型,而不能是基本類型
          ????????
          //
          List<int>?list?=?new?ArrayList<int>();
          ????????
          // 如果要往List中插入基本類型,可以給List指定其對應(yīng)的引用類型

          ????????List < Integer > ?list? = ? new ?ArrayList < Integer > ();
          ????????list.add(
          12
          );
          ????????list.add(
          23
          );
          ????????list.add(
          100
          );
          ????????
          int ?value? = ? 0
          ;
          ????????
          int ?length? =
          ?list.size();
          ????????
          ????????
          for ( int ?i? = ? 0 ;?i? < ?length;?i ++ )?
          {
          ????????????value?
          =
          ?list.get(i);
          ????????????System.out.println(value);
          ????????}

          ????}

          ????
          /**
          ?????*?
          @param ?args
          ?????
          */

          ????
          public ? static ? void ?main(String[]?args)? {
          ????????
          // ?TODO?自動生成方法存根

          ????????safefulList();
          ????????intList();
          ????}

          }

          上例的運行結(jié)果我就不給出了,太簡單了,估計你還沒看完程序就已經(jīng)知道結(jié)果了。需要說明的是,當(dāng)采用引用類型制定類型,而插入的是基本類型數(shù)據(jù)時,會帶來額外的開銷,這就是裝箱和解箱的開銷(boxing and unboxing)。泛型是一門藝術(shù),需慢慢琢磨方能體會它的美。

          posted on 2006-11-29 22:09 lotusswan 閱讀(704) 評論(0)  編輯  收藏 所屬分類: Tiger學(xué)習(xí)筆記
          主站蜘蛛池模板: 台南县| 曲松县| 营山县| 乐平市| 平塘县| 德格县| 荔浦县| 台东县| 绥宁县| 武穴市| 沛县| 临汾市| 沙湾县| 郴州市| 深水埗区| 定安县| 平定县| 河池市| 屯留县| 民权县| 北碚区| 刚察县| 石景山区| 安国市| 抚松县| 抚州市| 滁州市| 绵阳市| 凯里市| 囊谦县| 陇南市| 共和县| 奇台县| 富川| 东丽区| 岗巴县| 岳阳市| 九台市| 望谟县| 罗山县| 宽甸|