心的方向

          新的征途......
          posts - 75,comments - 19,trackbacks - 0
          <2008年11月>
          2627282930311
          2345678
          9101112131415
          16171819202122
          23242526272829
          30123456

          常用鏈接

          留言簿(1)

          我參與的團(tuán)隊

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          收藏夾

          3G

          IC卡

          J2EE系統(tǒng)架構(gòu)

          linux

          python

          RCP

          Struts2

          XFire

          我參與的團(tuán)隊

          收藏Blog

          數(shù)據(jù)庫

          資料

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

          本文鏈接: http://blog.csdn.net/jrq/archive/2005/10/27/517428.aspx

          正文:

          1. 為了方便按列作外循環(huán),想把ArrayList構(gòu)造成一個二維數(shù)組,如下:

              ......

            ArrayList result=GetResult();

            int n=result.size();

            String[][] myArray=new String[n][]; //定義二維數(shù)組
           
            for (int i=0;i<n;i++)  //構(gòu)造二維數(shù)組
            {
              ArrayList tempArray= (ArrayList)result.get(i);
              myArray[i]=(String[])tempArray.toArray();
            }

            ......

          程序可以編譯通過。

          但在運行到myArray[i]=(String[])tempArray.toArray()時,出現(xiàn)java.lang.ClassCastException的錯誤,很奇怪。

          花了一晚上時間,查了N多資料,總算搞定了?,F(xiàn)把問題記錄下來,以備參考。

          2. 此事從頭說起。  

          ArrayList類擴(kuò)展AbstractList并執(zhí)行List接口。ArrayList支持可隨需要而增長的動態(tài)數(shù)組。

              ArrayList有如下的構(gòu)造函數(shù):
            
                  ArrayList( )
                  ArrayList(Collection c)
                  ArrayList(int capacity)

          如果調(diào)用new ArrayList()構(gòu)造時,其默認(rèn)的capacity(初始容量)為10。

          參見ArrayList源碼,其中是這樣定義的:

              public ArrayList() {
            this(10);
               }

          默認(rèn)初始化內(nèi)部數(shù)組大小為10。為什么是10?不知道。可能SUN覺得這樣比較爽吧。

          程序編譯后執(zhí)行ArrayList.toArray(),把ArrayList轉(zhuǎn)化為數(shù)組時,該數(shù)組大小仍為capacity(為10)。

          當(dāng) 裝入的數(shù)據(jù)和capacity值不等時(小于capacity),比如只裝入了5個數(shù)據(jù),數(shù)組中后面的(capacity - size)個對象將置為null,此時當(dāng)數(shù)組強(qiáng)制類型轉(zhuǎn)換時,容易出現(xiàn)一些問題,如java.lang.ClassCastException異常等。

          解決辦法是:在用ArrayList轉(zhuǎn)化為數(shù)組裝數(shù)據(jù)后,使用trimToSize()重新設(shè)置數(shù)組的真實大小。


          3. 本例修改后的代碼修如下,可順利運行:

              for (int i=0;i<n;i++)  //構(gòu)造二維數(shù)組
                {
                      ArrayList tempArray= (ArrayList)result.get(i);
                      myArray[i]=(String[])tempArray.toArray(new String[0]);   //注意此處的寫法
                 }

           看看下面這些也許就明白了--

          ArrayList.toArray()之一:

          public Object[] toArray() {
            Object[] result = new Object[size];
            System.arraycopy(elementData, 0, result, 0, size);
            return result;
          }

          返回ArrayList元素的一個數(shù)組,注意這里雖然生成了一個新的數(shù)組,但是數(shù)組元素和集合中的元素是共享的,Collection接口中說這個是安全的,這是不嚴(yán)格的。

          下面的例子演示了這個效果。
           
             ArrayList al=new ArrayList();
             al.add(new StringBuffer("hello"));
             Object[] a=al.toArray();
             StringBuffer sb=(StringBuffer)a[0];
             sb.append("changed");  //改變數(shù)組元素同樣也改變了原來的ArrayList中的元素
             System.out.println(al.get(0));    

          這里不要用String來代替StringBuffer,因為String是不可變的。


          ArrayList.toArray()之二:

          public Object[] toArray(Object a[]) {
            if (a.length < size)
              a = (Object[])java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size);
             System.arraycopy(elementData, 0, a, 0, size);
             if (a.length > size)
                a[size] = null;
             return a;
          }

          這個方法有可能不需要生成新的數(shù)組,注意到如果數(shù)組a容量過大,只在size處設(shè)置為null。

          如果這個數(shù)組a足夠大,就會把數(shù)據(jù)全放進(jìn)去,返回的數(shù)組也是指向這個數(shù)組,(數(shù)組多余的空間存儲的是null對象);要是不夠大,就申請一個跟參數(shù)同樣類型的數(shù)組,把值放進(jìn)去,然后返回。


          4. 網(wǎng)上的資料一:

            public String[] getPlatformIDList()
           
            {
                  Vector result = new Vector();
                  try
                  {
                      Statement stmt = conn.createStatement();
                      String sql = "SELECT PlatformID FROM Platform";
                      rs = stmt.executeQuery(sql);
                      while(rs.next())
                      {
                          result.add(rs.getString(1));
                      }       
                      if (result.size() > 0)
                      {
                          String[] str = (String[]) result.toArray(); // 出現(xiàn)ClassCastException
                          return str;
                      }
                      else
                          return null;
                  }
                  catch(Exception e)
                  {
                      System.err.println(e);
                      return null;
                  }
                  finally
                  {
                      try
                      {
                          rs.close();
                          conn.close();
                      }
                      catch(Exception e2)
                      {}
                  }
              }

              程序運行后,發(fā)現(xiàn)不能將Vector類經(jīng)過toArray()方法得到的Object[]直接轉(zhuǎn)換成String[]。

              找到用另一個帶有參數(shù)的 toArray(T[] a)方法才可以。

              將該語句改為:

              String[] str = (String[]) result.toArray(new String[1]);即告訴Vector,我要得到的數(shù)組的類型。

              回想一下,應(yīng)該是java中的強(qiáng)制類型轉(zhuǎn)換只是針對單個對象的,想要偷懶,將整個數(shù)組轉(zhuǎn)換成另外一種類型的數(shù)組是不行的。


          5. 網(wǎng)上的資料二:

              正確使用List.toArray()--
           
             在程序中,往往得到一個List,程序要求對應(yīng)賦值給一個array,可以這樣寫程序:
           
              Long [] l = new Long[list.size()];
              for(int i=0;i<list.size();i++)
                  l[i] = (Long) list.get(i);
           
              要寫這些code,似乎比較繁瑣,其實List提供了toArray()的方法。
              但是要使用不好,就會有ClassCastExceptiony異常。究竟這個是如何產(chǎn)生的,且看代碼:

                  List list = new ArrayList();
                  list.add(new Long(1));list.add(new Long(2));
                  list.add(new Long(3));list.add(new Long(4));
                  Long[] l = (Long[])list.toArray();
                  for(int i=0; i<l.length; i++)
                      System.out.println(l[i].longValue());

              紅色代碼會拋java.lang.ClassCastException。

              當(dāng)然,為了讀出值來,你可以這樣code:

                  Object [] a =  list.toArray();
                  for(int i=0;i<a.length;i++)
                      System.out.println(((Long)a[i]).longValue());

              但是讓數(shù)組丟失了類型信息,這個不是我們想要得。


              toArray()正確使用方式如下:

                  1)  Long[] l = new Long[<total size>];
                        list.toArray(l);
           
                  2)  Long[] l = (Long []) list.toArray(new Long[0]);

                  3)  Long [] a = new Long[<total size>];
                        Long [] l = (Long []) list.toArray(a);

          6. 總結(jié)補充:

                java sdk doc 上講:
           
                public Object[] toArray(Object[] a)

                a--the array into which the elements of this list are to be stored, if it is big enough; otherwise, a new array of the same  runtime type is allocated for this purpose.

                如果這個數(shù)組a足夠大,就會把數(shù)據(jù)全放進(jìn)去,返回的數(shù)組也是指向這個數(shù)組,(數(shù)組多余的空間存儲的是null對象);要是不夠大,就申請一個跟參數(shù)同樣類型的數(shù)組,把值放進(jìn)去,然后返回。
           
               需要注意的是:你要是傳入的參數(shù)為9個大小,而list里面有5個object,那么其他的四個很可能是null , 使用的時候要特別注意。

          7. 完畢。

           

                                                                                                                        J.R.Q.

                                                                                                              2005.10.27凌晨于廣州 

          posted @ 2010-06-25 00:49 阿偉 閱讀(1219) | 評論 (0)編輯 收藏

          之前看網(wǎng)上有人發(fā)帖說有個解決辦法是viewservlet.jar下找到org/eclipse/birt/report/utility下找到ParameterAccessor.class文件,現(xiàn)在要修改這個文件的源代碼, 

          你可以在你從CVS中簽出的源代碼中的org.eclipse.birt.report.viewer/birt/WEB-INF/classes/org/eclipse/birt/report/utility文件夾中找到ParameterAccessor.java文件,在這個java文件中找到這行:

          public static final String UTF_8_ENCODE = "UTF-8"; //$NON-NLS-1$

          將這行改為

          public static final String UTF_8_ENCODE = "GBK"; //$NON-NLS-1$

          然后將這個編譯好的class文件壓縮到viewservlets.jar的同等目錄下,替換原來的文件”,本人也試了這種方法,但沒見湊效,不過上面的解決方法好像是在birt2.1的環(huán)境下,這個沒仔細(xì)試,也許對birt2.1有效吧。


          本人使用birt版本2.3,解決辦法如下:
          在JSP中調(diào)用BIRT報表時,傳的參數(shù)中有中文字符,即URL中包含中文字符,這時在BIRT端接收到的參數(shù)拼SQL語句后發(fā)現(xiàn)中文字符被轉(zhuǎn)碼,造成SQL中的條件不正確。
          因為在JSP中調(diào)用BIRT是在一個JS腳本中,因此要想辦法在JS中先將中文轉(zhuǎn)成UTF-8,并且在BIRT獲取參數(shù)后再將UTF-8轉(zhuǎn)換回中文即可。
          實現(xiàn)代碼:
          頁面JS:
          Var mychecktype = “中文”;
          sqlWhere+="and t.CHECK_TYPE = '"+escape(encodeURI(mychecktype))+"'";

          BIRT腳本:
          sql+=decodeURI(mycondition);

          posted @ 2009-07-02 09:56 阿偉 閱讀(2545) | 評論 (1)編輯 收藏
           問題:

          頁面中寫了一個函數(shù)a,在另一個函數(shù)中調(diào)用,頁面用的是一個iframe框架,即通過iframesrc參數(shù)來刷新iframe中的頁面,每次在第一次調(diào)用函數(shù)a時沒問題,但第二次點擊按鈕調(diào)用函數(shù)a時老報“缺少函數(shù)”的錯誤?

          function a(var1)
          {
            ...
            return a;
          }

          第一次 alert(a(var1)) 沒有問題,第二次就出錯了

          解決:
           

          后來發(fā)現(xiàn)函數(shù)中返回值變量名和函數(shù)名定義為同一個名字,把返回值變量名改成其它名字后問題就解決了,好弱的一個問題啊,折騰了我半天,氣憤!

          改成 return b 就好了 -_-

          posted @ 2008-11-27 14:58 阿偉 閱讀(2272) | 評論 (0)編輯 收藏
          主站蜘蛛池模板: 宜城市| 鹤峰县| 郧西县| 淮安市| 隆昌县| 遵义县| 突泉县| 新兴县| 昌图县| 高要市| 高陵县| 威海市| 宁南县| 永兴县| 尼勒克县| 甘南县| 保定市| 建宁县| 大宁县| 汾阳市| 石嘴山市| 温州市| 商都县| 博乐市| 合江县| 金坛市| 清苑县| 临湘市| 柘城县| 宜兰市| 宁乡县| 沙雅县| 三门峡市| 肥东县| 聂拉木县| 太湖县| 化州市| 津南区| 江都市| 乐业县| 札达县|