目前分類:Java基本功 (18)

瀏覽方式: 標題列表 簡短摘要

  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) 人氣()

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

public static String getEncodingString(String str, String srcEnc, String targetEnc) {

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

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

public static void main(String[] args) throws Exception

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

  以前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) 人氣()

  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) 人氣()

  都快發行JDK 7了,JDK 5的annotation在survey Guice才知道怎麼回事。Guice怎麼使用anntation做Module bind留待後面。原來annotation是一個介面啊!如下寫一個interface:

public @interface Debug{}

  就可以用@Debug在method之上。interface的定字前就得加個@。再根據Guice的飯粒這麼定義@Blue這個annotation當解說:

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

  import static是JDK 5.0引進的語法蜜糖,例下:

import static java.lang.System.out;

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

  以前常用過水的網頁做些偷吃步的工作,這次是用於測試,太久沒寫反而忘了。需求是要把測試資料以List<Map>形式放進Session傳到被測網頁,而測試資料可以由測試人員在網頁上填,其Solution如下:

1.Input Form JSP:

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

  文化中心借來一本O'Reilly出版的Head First Design Patterns,的確是寫得相當好的Java書。但我沒料到的是,以為第二簡單的Singleton Pattern(最簡單的是Iterator),原來我還是存著不少誤解。使用Singleton的觀念匯整如下:

  1. 使用全域變數率先實體化會比Singleton延遲實體還要浪費資源。
  2. 若使用兩個以上class loader,還是可能出現Singleton有多個現象。
  3. 不建議使用static class,因為static class的初始化是被JVM掌握,而非程式,可能有潛在Bug。
  4. 在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存取

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

java -Xms1024m -Xmx2048m -XX:ThreadStackSize=512 -XX:MaxPermSize=256 - jar XX.jar

XX:ThreadStackSize  >> java.lang.StackOverflowError

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

  第一種,是會丟出SocketTimeoutExcpetion的,有找到Host但一直等不到回應。可以設socket.setSoTimeout(timeout)。

  第二種,是會丟出UnknownHostException的,是找不到Host的,若在Local找不到這個Host很快就丟,但在Server通常內建一堆DNS解析IP,等全部巡完一輪都要等好久。所以時間內找不到就視為UnknownHostException作法如下:

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

  使用URL物件去連一個網址,有時會出現如右的exception: java.net.MalformedURLException: illegal character in url。程式如下:

URL url = new URL(urlStr);

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

  很早我就知道這個需求,本來想抄捷徑使用cron table去定時執行tar指令,將Log檔壓縮備份再刪Log檔。但想想,還是寫的工具程式好了,以下飯粒抄自O'Reilly的Java IO一書。

private void copy(InputStream in, OutputStream out)  throws IOException {        // Stream Copy

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

  有需求是提供一個,給外部系統呼叫。按HTTP協議,成功就回200的Status,失敗回400或503等標準Status。間接明白Servlet在method命名前綴也有玄機。

  後來需求改為回200同時回一個簡單的頁面。而之前回Status方式是用HttpServletResponse物件的sendError(HttpServletResponse.SC_OK),結果才知道send開頭的method是一個commit動作,因為sendError之後無法再使用HttpServletResponse物件的setStatus或getWriter去產出頁面。是故,本來是sendError(HttpServletResponse.SC_OK)改成

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

  對初學Java的人來說,java.util的Calendar設計的有點奇怪,取得instance是使用Calendar.getInstance(),getInstance這個method name是Singleton pattern慣用命名,會有以下的誤解:

  Calendar cal = Calendar.getInstance();

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

  Java IO分二進位和純文字的資料流,各以InputStream / OutputStream與Reader / Writer為代表。Socket預設為二進位流,若要轉為純文字,則需InputStreamReader / OutputStreamWriter轉換,其法如下:

InputStreamReader isr = new InputStreamReader(socket.getInputStream());

OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());

  欲以文字列方式讀取,採用BufferedReader的readLine()去讀會有個陷阱。就是寫入的地方若沒加上換行符號,readLine會一直等待讀到換行符號為止。是故Output應如下:

OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());

osw.write(msg + "\n");  // msg字串結尾若有換行則不必加\n。

osw.flush();                 // 記得出清。

  後來我試著用PrintWriter替代OutputStreamWriter,使用println替代write以省略額外加入換行符號可行,仍需flush。

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

雖然自己有保留範例,但難保不會遺失資料,而且記性變差,知道有Reflection可以運用,但都需要上網查詢,還是把以前做過的Sample貼上來,要回顧資料時就不難了。以下分別Demo ClassLoader、Constructor與Invoke的功能:
Noname1.java Demo用的Class

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

之前一直誤解一個Servlet的instance是一個Thread,其實一個Request instance才是.
寫好的Servlet Class被Web Container載入,在第一次被call後才會new出一個實體,之後再call仍是同一份實體.

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