PIXNET Logo登入

Jemmy Walker

跳到主文

部落格全站分類:不設分類

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 10月 22 週五 201018:58
  • Java Collection二三事

  Java的Collection在multi-thread下有些不同的狀況。以Queue介面為例,若使用LinkedList,因為非thread-safe,可能丟出NoSuchElementException,而若使用thread-safe的LinkedBlockingQueue,則在offer時因塞進Null而丟出NullPointerException,意謂LinkedBlockingQueue不可offer Null。   Collection提供了toArray()和toArray(T [])兩種method轉陣列,第一個return Object[]好理解,第二個帶泛型的陣列後來才搞懂,原來要這樣TestBean[] = query.toArray(new TestBean[]),參數是要求一個allocate好的陣列,toArray(T [])不會聰明到在內部做reflection。
(繼續閱讀...)
文章標籤

Jemmy 發表在 痞客邦 留言(0) 人氣(271)

  • 個人分類:Java基本功
▲top
  • 7月 22 週四 201019:05
  • 字串轉碼

  上次介紹的是檔案的Big5轉UTF-8,但把字串轉成資料流再轉換編碼,似乎比檔案轉碼來得複雜一點:

public static String getEncodingString(String str, String srcEnc, String targetEnc) {
    ByteArrayInputStream bais = null;
    BufferedReader br = null;
    try {
        bais = new ByteArrayInputStream(str.getBytes(srcEnc));
        br = new BufferedReader(new InputStreamReader(bais, srcEnc));
        ByteArrayOutputStream boas = new ByteArrayOutputStream();
        OutputStreamWriter osw = new OutputStreamWriter(boas, targetEnc);
        osw.write(br.readLine());
        osw.flush();
        byte[] ba = boas.toByteArray();
        for (int i=0; i<ba.length; i++) {
            System.out.printf("%02X ", ba[i]);
        }
        return boas.toString(targetEnc);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

  上面的method傳進的參數是要轉碼的字串、字串原編碼、要轉碼之編碼。比檔案轉碼多出的地方是:
  • 在字串轉成ByteArrayInputStream時,getBytes要指定來源編碼。
  • 轉碼到ByteArrayOutputStream,toString也要指定目的編碼。
  •   以下以"一"作為測試之用,"一"在Unicode編碼是\u4E00,在Big5編碼是A440。Java字串預設編碼是Unicode,切勿String str = "一"; 這樣宣告,它必定為Unicode編碼,除非javac -encoding Big5來編譯。以下是測試用例:

    byte baChOneBig5[] = new byte[2];
    baChOneBig5[0] = (byte)0xA4;  // Big5編碼A440 ==> 0xA4, 0x40
    baChOneBig5[1] = (byte)0x40;
    String char1 = new String(baChOneBig5, "BIG5"); // 由byte[]轉成String就可以是Big5字串
    System.out.println("Big5: " + char1);
    System.out.println(" >> " + getEncodingString(char1, "Big5", "Unicode"));
    System.out.println(" >> " + getEncodingString(char1, "Big5", "UTF-8"));

      得到的結果如下:

    Big5: 一
    FE FF 4E 00  >> 一  Unicode編碼\u4E00, 但不知前面的FEFF是怎麼來的。
    E4 B8 80  >> 一     UTF-8在"一"的編碼。

      其實在String char1 = new String(baChOneBig5, "BIG5");的時候,若Integer.toHexString(char1.charAt(0)).toUpperCase()會得到什麼編碼?其實不是A440,而是4E00。在存成Java String時,還是Unicode。
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(3,741)

    • 個人分類:Java基本功
    ▲top
    • 6月 19 週六 201017:37
    • Big5轉UTF-8

      Big5轉UTF8的方式在數年前就自O'Reilly的Java IO一書學會了,但至今還是犯下相似的錯誤。本來以為可以藉用StringReader將Big5編碼的String轉成Stream再轉換到UTF8,甚至妄想以為不須指定來源編碼。事實上還是要中規中矩的把String轉成Byte Array,再轉成Stream時指定其來源編碼。

    public static void main(String[] args) throws Exception
    {
        BufferedReader br = new BufferedReader(
            new InputStreamReader(new FileInputStream("./B.xml"), "Big5"));     //檔案

            // new InputStreamReader(new ByteArrayInputStream(str.getBytes(), "Big5")); //字串
        PrintWriter pw = new PrintWriter(
            new OutputStreamWriter(new FileOutputStream("./B2.xml"), "UTF8"));
        String line = br.readLine();
        while (line != null) {
            System.out.println(line);
            pw.write(line);
            line = br.readLine();
        }
        pw.flush();
        pw.close();
    }

      Survey期間也發現幾個有趣及易犯錯的地方。比如XML若指定UTF-8編碼:<?xml version="1.0" encoding="UTF-8"?>,不能用UTF8。還有以下三種取得系統編碼方式,結果還真的都不太一樣:

    logger.debug("Encoding:{}", System.getProperty("file.encoding")); // ISO8859-1
    logger.debug("Charset:{}", Charset.defaultCharset().name());      // ISO-8859-1
    logger.debug("OutputStream:{}", (new OutputStreamWriter(System.out)).getEncoding()); // ISO8859_1

    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(2,508)

    • 個人分類:Java基本功
    ▲top
    • 6月 14 週一 201020:32
    • Collection生死戀

      以前3rd party的朋友問我,List list = new ArrayList(),想把裡面的值清空再替代新值,不能使用list = null再list = new ArrayList()嗎?他是以C語言角度來寫Java,後來我回答他用list.clear()就OK了。今天也遇到類似的問題,想把list傳給Thread後清空重複使用,發現不能用list.clear(),連帶的Thread裡的list reference跟著被清空。反而在傳完list給Thread後,改先list = null再list = new ArrayList()就可以work。在Java的Resource Recycle機制,即使instance被設為null,只要還有別的物件參考到它,基本上還不會歸還給記憶體,直到沒有物件參考它時。有時…會忘了這些基本功。
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(125)

    • 個人分類:Java基本功
    ▲top
    • 4月 13 週二 201000:49
    • web.xml載入順序

      Servlet我並沒研究那麼透徹,只是在踹Framework時,老需要設定一堆Filter和Listener,引發要整理的想法。這篇是我沒有親身實作過,直接抄參考他人的Blog剪貼^^|||。在這篇對岸Blog內容寫道,web.xml在Load的順序是:context-param -> listener -> filter -> servlet。Filter比較好懂,針對mapping的url-pattern進行上下其手,不,是過濾的動作,多個Filter的話,其載入順序是按<filter-mapping>先後。而Listener,根據良葛格的網站清楚說明,它是針對ServletContext、Session、Request這三個層級記憶體(內存)的初始化與銷毀,以及每個層級的Attribute的add和remove。算起來有六個Listener,而還有HttpSessionActivationListener用於序列化,及HttpSessionBindingListener用於attribute被設置時觸發,一共八個。當然Listener了解即可,已有很多優良實作,web Listener最有名莫過於Spring,這也是context-param會在Listener之前先被Load的原因。   題外話,Context的譯詞大多是上下文、背景或內容。對初學者乍聽之下,還是有點摸不著邊,也難舉例。而我第一次接觸Context這單字是Perl,電腦天才唐鳳譯之為語境,起初以為和Spring的Context定義應該不同,後來覺得是相通的。語境在Perl的舉例是這樣,對你說:[吃飽沒?]這句話並沒主詞,但主詞是You顯而易見,同在一個語境。再以本Blog的技術文章為例,來參訪者大都要有一定中文程度及技術底子,語境是懂中文和懂程式,對其他人而言,懂中文不懂程式還是屬於火星文。而在兩個Context情形也有,和同事去吉隆坡出差,因為不懂英文需借助翻譯,等同Load兩個不同的Context,在程式裡交互運作,這一般專案系統比較不會用多Context。
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(306)

    • 個人分類:Java基本功
    ▲top
    • 3月 21 週日 201022:13
    • Java基本功:annotation usage

      都快發行JDK 7了,JDK 5的annotation在survey Guice才知道怎麼回事。Guice怎麼使用anntation做Module bind留待後面。原來annotation是一個介面啊!如下寫一個interface: public @interface Debug{}   就可以用@Debug在method之上。interface的定字前就得加個@。再根據Guice的飯粒這麼定義@Blue這個annotation當解說:

    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
    @Retention ( RetentionPolicy.RUNTIME )
    @Documented

    @BindingAnnotation
    public @interface Blue {}

      上例紅字的annotation皆出自java.lang.annotation:
  • @Target:指@Blue這個anntoation可以修飾哪些層級,上例有FIELD(廣域變數)、METHOD和建構子。此外,還有TYPE(修餘class、interface和enum)、PARAMETER(METHOD上的參數)、LOCAL_VARIABLE(區域變數)、ANNOTATION_TYPE(Annotation)和PACKAGE。
  • @Retention:指@Blue在什麼時期有作用,RUNTIME(執行期能被reflection用)、CLASS(預設,Runtime)和SOURCE(編譯時期)
  • @Document:將@Blue產出JavaDoc。
  • @Inherited:宣告該@annotation所注釋的類別若被繼承,其子類別亦被注釋。
  •   而通常annotion括號內設計內賦值,也是在@interface裡設計,例如像@Retention,應該是這樣: public @interface Retention {
        public enum RentionPolicy {SOURCE, CLASS, RUNTIME};
        RentionPolicy rentionPolcy() default RentionPolicy.CLASS;
        // 以下是說明傳回其它型態的賦值舉例
        String op1();   // @Retention(op1=”Jemmy”), 若只有op1,可能連method name都可省略了
        String[] op2(); // @Retention(op1={”Jemmy”,”Tsai”})
        boolean op3();  // @Retention(op3=true)
        /* 或是像這樣
        @Retention(
            op1=”Jemmy”, op2={“Jemmy”,”Tsai”}, op3=true
        )
        */
    }
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(324)

    • 個人分類:Java基本功
    ▲top
    • 2月 14 週日 201016:39
    • Java基本功:import static

      import static是JDK 5.0引進的語法蜜糖,例下:
    import static java.lang.System.out;
        public class HelloWorld {
            public static void main(String[] args) {
            out.println("Hello! World!");
        }
    }
      如此一來就不用老打System.out.println,其作用就像C語言的#define(巨集),javac(Java編譯器)遇到out會擴展為System.out,少打幾行字。當然用在System.out太殺雞用牛刀,比較常用在內含豐富的static class library,如JUnit、Math等。當然若引進相同的Class name,編譯器當然會報錯。
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(212)

    • 個人分類:Java基本功
    ▲top
    • 1月 31 週日 201015:57
    • Java基本功:過水的網頁

      以前常用過水的網頁做些偷吃步的工作,這次是用於測試,太久沒寫反而忘了。需求是要把測試資料以List<Map>形式放進Session傳到被測網頁,而測試資料可以由測試人員在網頁上填,其Solution如下:
    1.Input Form JSP:
    <table>
        <tr>
            <td> Title 1</td>
            <td> Title 2</td>
        </tr>
        <% for (int i=0; i<20; i++) { %>
        <tr>
            <td> <Input type="text" name="T1"/></td>
            <td> <Input type="text" name="T2"/></td>
        </tr>
        <% } %>
    </table>
    上例的JSP,會創造T1、T2陣列的Request,之後Submit到過水的頁面。
    2.過水頁面
    <%  // 傳同名input name會是String陣列取得,是故一定要用getParameterValues,若單一值則用getParameter。
    String[] T1s = request.getParameterValues("T1");
    String[] T2s = request.getParameterValues("T2");
    … // 轉成List<Map<key, data>>
    session.setAttribute("list", list);             // 步驟2:寫到Session
    response.sendRedirect("tested.jsp");       // 步驟3:導到受測url。
    %>
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(112)

    • 個人分類:Java基本功
    ▲top
    • 10月 03 週六 200923:29
    • Java基本功:Singleton

      文化中心借來一本O'Reilly出版的Head First Design Patterns,的確是寫得相當好的Java書。但我沒料到的是,以為第二簡單的Singleton Pattern(最簡單的是Iterator),原來我還是存著不少誤解。使用Singleton的觀念匯整如下:
  • 使用全域變數率先實體化會比Singleton延遲實體還要浪費資源。
  • 若使用兩個以上class loader,還是可能出現Singleton有多個現象。
  • 不建議使用static class,因為static class的初始化是被JVM掌握,而非程式,可能有潛在Bug。
  • 在Multi-Threads下,需要在getInstance()前加synchronized防止有兩個thread進入存取,但效能可能下降100倍。是故有以下兩種解法:
    1. private statice Singleton uniqueInstance = new Singleton();  // 不採延遲實體化方式
    2. 使用JDK 5.0才有的double-checked locking,在getInstance()內容寫法如下:
  • private volatile static Singleton uniqueInstance;   // volatile確保初始化Singleton實體時,實體可正確被Multi-Threads存取 private static Singleton getInstance() {                   // JDK 1.4及更早版本不適用
        if (uniqueInstance == null) {
            synchronized (Singleton.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new Singleton();
                }
            }
        }
    }
    這招是另一位Bob Lee寫的Singleton,相當Simple:

    public class Singleton {     
      static class SingletonHolder {     
        static Singleton instance = new Singleton();     
      }     
        
      public static Singleton getInstance() {     
        return SingletonHolder.instance;     
      }        
    }
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(415)

    • 個人分類:Java基本功
    ▲top
    • 8月 28 週五 200912:04
    • Java基本功:調整JVM的Memory和Stack

    java -Xms1024m -Xmx2048m -XX:ThreadStackSize=512 -XX:MaxPermSize=256 - jar XX.jar XX:ThreadStackSize  >> java.lang.StackOverflowError XX:MaxPermSize (預設64MB) >> java.lang.OutOfMemoryError: PermGen space Xms (記憶體最小配置) Xmx (記憶體最大配置) >> java.lang.OutOfMemoryError:heap space 其它的如下: -Xms3072M -Xmx3072M -XX:NewSize=256M -XX:MaxNewSize=256M -XX:PermSize=256M -XX:MaxPermSize=256M -XX:SurvivorRatio=128 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:MaxTenuringThreshold=1 -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+DisableExplicitGC -XX:+OverrideDefaultLibthread
    (繼續閱讀...)
    文章標籤

    Jemmy 發表在 痞客邦 留言(0) 人氣(1,228)

    • 個人分類:Java基本功
    ▲top
    12»

    自訂側欄

    自訂側欄

    個人資訊

    Jemmy
    暱稱:
    Jemmy
    分類:
    不設分類
    好友:
    累積中
    地區:

    熱門文章

    • (18,362)Windows route初體驗
    • (2,912)Java在換行字元的issue
    • (2,508)Big5轉UTF-8
    • (1,417)非我族類的DataTables.js:分頁和排序無作用原因
    • (1,319)Oracle的Array型態定義與存取
    • (776)OGG for Java開發
    • (542)Perl的跨行比對
    • (436)ORA-08002
    • (224)Log4J依不同class產出不同log file之二,加Daily Rolling
    • (73)Notes的Agent二三事

    文章分類

    • PostgreSQL (1)
    • Ruby (6)
    • 圖書 (18)
    • 旅行 (8)
    • OSGi (13)
    • 健康 (9)
    • Google (6)
    • 歷史 (5)
    • Spring-Security (5)
    • Java Script (11)
    • Log (8)
    • 娛樂 (25)
    • IT趨勢 (12)
    • 心情 (92)
    • 組織 (41)
    • Java基本功 (18)
    • Regex (19)
    • 新聞與政治 (46)
    • 電腦和網際網路 (47)
    • Maven (28)
    • Spring (31)
    • LotusNotes (12)
    • Java (60)
    • Oracle (17)
    • Struts (21)
    • jQuery (10)
    • 未分類文章 (1)

    最新文章

    • JDOM解析XML字串(非檔案)
    • Android SDK不能用於JDK 64bit
    • 非我族類的DataTables.js:分頁和排序無作用原因
    • java.lang.IllegalStateException: Committed之解
    • PostgreSQL二三事
    • Form/Field V.S. Document/Item
    • Spring Mail
    • Ant generate manifest.mf的class-path清單
    • dhcp.bat
    • Java update Notes的DateTime欄位

    最新留言

    • [21/07/31] D 於文章「複習一下Servlet的機制...」留言:
      請問更換瀏覽器 Servlet的instance vari...
    • [17/05/04] 訪客 於文章「設定Source編碼...」留言:
      謝謝你~~...
    • [15/08/23] 洪秀柱 於文章「UltraEdit轉大小寫...」留言:
      此破解法可用於 UEstudio UltraEdit V2...
    • [10/10/15] Jemmy 於文章「Perl的跨行比對...」留言:
      哈! 學長, 好久不見了。幸虧這案子沒有Nested Tag...
    • [10/10/14] Benson 於文章「Perl的跨行比對...」留言:
      如果有Nested Tag, 這就不太適用; 我有時還是乖乖...
    • [10/05/25] 世文 於文章「JSON-Lib初體驗...」留言:
      用心經營的blog~^^ 加油!<br />---<br ...
    • [10/05/15] Jemmy 於文章「千分位...」留言:
      你的解法太高深了, 有空再練^^...
    • [10/05/14] Benson 於文章「千分位...」留言:
      可能是 gxe, 不管是 perl or java, 你懂我...
    • [10/05/14] Jemmy 於文章「千分位...」留言:
      練功一下而已, 而且我是要用Java,所以無法用Perl...
    • [10/05/14] Benson 於文章「千分位...」留言:
      學弟,你的問題是什麼呢?是把在引號內數字逗號去掉嗎?s/\"...

    動態訂閱

    文章精選

    文章搜尋

    誰來我家

    參觀人氣

    • 本日人氣:
    • 累積人氣: