隨筆 - 20, 文章 - 0, 評論 - 0, 引用 - 0
          數(shù)據(jù)加載中……

          [導入]用java匿名類來簡化調(diào)試

          在Java中,匿名類(Anonymous inner classes)多用來處理事件(event handle)。但其實,它們對于debug也很有幫助。本文將介紹如何利用匿名類來簡化你的debug。

                我們該如何調(diào)試那些非自己源碼的方法調(diào)用呢?比方說,對Jbutton.setEnable()的調(diào)用。Java提供的匿名類,可以很好的解決這個問題。

                通常,當我們繼承一個類時,我們可以通過提供新的方法來覆蓋(override)該類中現(xiàn)有的方法:
                      
          public class MyButton extends JButton {   public void setVisible( boolean visible ) {      // Rolling our own visibility    }}
                在實例化(instantiate)MyButton類之后,任何對方法setVisible()的調(diào)用,都會調(diào)用上面代碼中的setVisible()方法。可問題是,我們不想僅僅為了覆蓋一個方法而繼承整個類,尤其是所需的實例(instantiation)很有限的時候。匿名類使得我們能在實例化的同時覆蓋方法。

          如果我們只想在某個JButton對象中加入我們自己的可視邏輯,那么我們可以在申明這個button對象的同時重寫這個方法:
                      
          JButton myButton = new JButton() 
          {   public void setVisible( boolean visible ) 
          {      // Rolling our own visibility    }};
                這段代碼都做了什么?花括號({})中間的代碼申明了setVisible()方法,并覆蓋了JButton類中的那個,但這僅限于myButton對象。我們沒有改變JButton類,也沒有申明一個新類,我們僅給了一個特殊的JButton對象它自己的可視邏輯。
          在面向?qū)ο笮g(shù)語中,myButton是一個從JButton類繼承而來的無名,也就是匿名,類的對象。

               這種創(chuàng)建匿名類并同時覆蓋方法的技術(shù)用在什么時候?假設你在編寫一段Swing程序,在你向一個GUI物件(element)中添加一個event listener(假設叫作ActionListener)之前,你已經(jīng)編寫了一段這種機制的代碼。現(xiàn)在,我們假設我們有個龐大的類,里面有很多按鈕,但是有一個按鈕時隱時現(xiàn),你想知道為什么會出這樣的異常情況,利用上面的代碼并在setVisible()方法上設置斷點。然后,當你運行你的程序時,你設置的斷點就會在恰當?shù)牡胤綍和3绦颉z查棧軌跡(stack trace),我們會發(fā)現(xiàn)沒有按所預期的那樣來調(diào)用setVisible()方法的原因并修復這個它。

               匿名類在debug類似這種源碼不可得的類的時候很有用。即便在源碼可得的情況下,在大量使用的方法(如setVisible)上設置斷點,也是件很麻煩的事情,因為我們在每個實現(xiàn)了setVisible()方法的類的對象上都要轉(zhuǎn)入斷點。而匿名類可針對某個特定的對象進行“外科手術(shù)”式的debug。




          文章來源:http://www.aygfsteel.com/supercrsky/articles/164590.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(96) | 評論 (0)編輯 收藏

          [導入]Java打包詳解

          jar文件聽說過嗎,沒有?或者陌生!好,沒關系,這就是我們的第一站:打包發(fā)布。

          為什么會有這個玩意呢,首先,這是jar的全稱:JavaTM Archive (JAR) file,是的,就是java存檔文件。這有點類似zip文件,想一想它是干什么的用的呢,壓縮!?沒錯就是要壓縮,將我們原先零散的東西放到一下,重新 組織,所有這些目的只有一個:方便!好了,不用管他是怎么壓縮的,我們的重點是哪些是我們要壓縮的(輸入),還有壓縮成了什么(輸出),進而將它發(fā)布(部 署)。

          那我們的輸入(要壓縮的東西)主要是class文件,還有輔助的資源(這其中可能有圖片,jsp文件,html文件等 等)。Jar技術(shù)在jdk1.1版本中就已存在,在1.2中又有了增強。接下來說說jar的好處吧,這是官方的描述:安全,快速下載,壓縮,獵取包,版本 化包,可攜。

          說了這么多,我們現(xiàn)在開始實施。

          先打開命令提示符(win2000或在運行框里執(zhí)行cmd命令,win98為DOS提示符),輸入jar Chelp,然后回車(如果你盤上已經(jīng)有了jdk1.1或以上版本),看到什么:

          用法:jar {ctxu}[vfm0Mi] [jar-文件] [manifest-文件] [-C 目錄] 文件名 ...

          選項:

          -c 創(chuàng)建新的存檔

          -t 列出存檔內(nèi)容的列表

          -x 展開存檔中的命名的(或所有的〕文件

          -u 更新已存在的存檔

          -v 生成詳細輸出到標準輸出上

          -f 指定存檔文件名

          -m 包含來自標明文件的標明信息

          -0 只存儲方式;未用zip壓縮格式

          -M 不產(chǎn)生所有項的清單(manifest〕文件

          -i 為指定的jar文件產(chǎn)生索引信息

          -C 改變到指定的目錄,并且包含下列文件:

          如果一個文件名是一個目錄,它將被遞歸處理。

          清單(manifest〕文件名和存檔文件名都需要被指定,按'm' 和 'f'標志指定的相同順序。

          示例1:將兩個class文件存檔到一個名為 'classes.jar' 的存檔文件中:


          jar cvf classes.jar Foo.class Bar.class

          示例2:用一個存在的清單(manifest)文件 'mymanifest' 將 foo/ 目錄下的所有文件存檔到一個名為 'classes.jar' 的存檔文件中:


          jar cvfm classes.jar mymanifest -C foo/ .

          來個小例子試試看:

          我們只有一個HelloWorld,如下:


          public class HelloWorld{
          public static void main(String[ ] args){
          System.out.println(“Hi, Hello World!”);
          }
          }

          將這個java文件存到C盤跟目錄下,ok,接下來,

          在先前打開的命令提示符下(跳轉(zhuǎn)到C盤提示符下),我們輸入javac HelloWorld.java,然后繼續(xù)輸入:jar  cvf  hello.jar  HelloWorld.class,回車后去你的C盤看看,多了什么,沒錯 hello.jar 。

          基本的步驟我們現(xiàn)在都知道了,你可以自己去嘗試一下隨著jar后面的參數(shù)的不同,結(jié)果有什么變化。
          緊接著我們看看如何運行我們的jar包。

          在進入正題之前,你要先打開我們剛剛做好的jar包看看,多了什么呢,META-INF目錄?再看看里面是什么,還有一個MANIFEST.MF文件是不是?用文本編輯器(我這里是UltraEdit)打開它看看:


          Manifest-Version: 1.0
          Created-By: 1.4.2 (Sun Microsystems Inc.)

          就是這樣。這里我們對它進行修改,加一句:Main-Class: HelloWorld (在第三行)。這個就是我們之前寫的那個類,也就是我們的入口類。也即,


          Manifest-Version: 1.0
          Created-By: 1.4.2 (Sun Microsystems Inc.)
          Main-Class: HelloWorld

          接下來,我們在命令提示符里執(zhí)行:


          jar  umf  MANIFEST.MF  app.jar (應該是hello.jar吧)

          這樣我們使用了我們自己的MANIFEST.MF文件對原來默認的進行了更新。你不妨可以再進去看看是不是添上了Main-Class: HelloWorld這一句。 (是嗎,我怎么沒試出來,提示java.io.FileNotFoundException:MANIFEST.MF(系統(tǒng)找不到指定的文件)怎么回 事?)

          Ok,這個最后的一步了,來驗證我們做的一切,在命令提示符中輸入:


          java -jar hello.jar(執(zhí)行)

          出現(xiàn)了什么, Hi, Hello World!

          我們再來看看jar文件在tomcat中發(fā)布,注意:在tomcat中我們就不能再用jar這種格式,而改war格式,它是專門用于web應用的,其實整個過程下來基本上和jar是類似的:

          先準備我們要打包的資源。

          找到存放tomcat的webapps目錄,進到其中,新建一個文件夾,這里命名為hello,再進去新建WEB-INF文件夾,再進去新建 classes文件夾,此時我們也將我們唯一的servlet,HelloWorld.java放到這里,在與classes目錄同級下建立一文件 web.xml。Ok,目前我們初步建立了一個簡單的web應用。

          這是HelloWorld.java:

          import java.io.*;
          import javax.servlet.*;
          import javax.servlet.http.*;
          public class HelloWorld extends HttpServlet {
          public void doGet(HttpServletRequest req, HttpServletResponse res)
          throws ServletException, IOException {
          res.setContentType(
          "text/html");
          PrintWriter out 
          = res.getWriter();
          out.println(
          "");
          out.println(
          "");
          out.println(
          "");
          out.println(
          "Hello, World!");
          out.println(
          "");
          }
          }
          //end here!
          對它編譯。下面是web.xml:
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
          <web-app>
          <servlet>
          <servlet-name>hello</servlet-name>
          <servlet-class>HelloWorld</servlet-class>
          </servlet>
          <servlet-mapping>
          <servlet-name>hello</servlet-name>
          <url-pattern>/HelloWorld</url-pattern>
          </servlet-mapping>
          </web-app>
          在命令提示符下進到先前創(chuàng)制的hello目錄下,執(zhí)行 jar cvf hello.war * ,我們便得到hello.war。將它拷貝至webapps目錄下,ok,來看最后一步,打開tomcat的目錄conf中的server.xml,加入:

          <Context path="/hello" docBase="hello.war" debug="0" reloadable="true"/>

          大功告成!運行它,啟動tomcat,后在瀏覽器中輸入http://localhost:8080/hello/HelloWorld,有了嗎?

          最后,如果你想用ant來完成以上的打包活動,下面就告訴你:
          對于jar來說。在build.xml中,


          <target name="jar">
          <jar destfile="${app_home}/hello.jar">
          <fileset dir="${dest}" includes="**"/>
          <!--fileset dir="${dest}" includes="**/action.properties"/-->
          </jar>
          </target>
          對于war,


          <war warfile="hello.war" webxml="./WEB-INF/web.xml">
          <fileset dir="html"/>
          <lib dir="lib/">
          <exclude name="oracle*.jar"/>
          </lib>
          <classes dir="build/servlets">
          <include name="**/*.class"/>
          </classes>
          </war>
          好了,就這么多,希望對你有點幫助。:)

          補充:

          jar基本操作:

          1. 創(chuàng)建jar文件

           



          jar cf jar-file input-file(s)
          c---want to Create a JAR file.
          f---want the output to go to a file rather than to stdout.
          eg: 1)jar cf myjar.jar query_maintain_insert.htm
          2)jar cvf myjar.jar query_maintain_insert.htm
          v---Produces verbose(詳細的) output.


            3)jar cvf myjar.jar query_maintain_insert.htm mydirectory
          4)jar cv0f myjar.jar query_maintain_insert.htm mydirectory
          0---don't want the JAR file to be compressed.
          5)jar cmf MANIFEST.MF myjar.jar yahh.txt
          m---Used to include manifest information from an existing manifest file.
          6)jar cMf MANIFEST.MF myjar.jar yahh.txt
          M---the default manifest file should not be produced.
          7)jar cvf myjar.jar *
          *---create all contents in current directory. 

            2. 察看jar文件   

           


            jar tf jar-file
          t---want to view the Table of contents of the JAR file.
          eg: 1)jar vft yahh.jar
          v---Produces verbose(詳細的) output.  

            3. 提取jar文件  

           


            jar xf jar-file [archived-file(s)]
          x---want to extract files from the JAR archive.
          eg: 1)jar xf yahh.jar yahh.txt(僅提取文件yahh.txt)

            2)jar xf yahh.jar alex/yahhalex.txt(僅提取目錄alex下的文件yahhalex.txt)  

            3)jar xf yahh.jar(提取該jar包中的所有文件或目錄)  

            4. 修改Manifest文件  

           


            jar cmf manifest-addition jar-file input-file(s)
          m---Used to include manifest information from an existing manifest file.  

            5. 更新jar文件  

           


            jar uf jar-file input-file(s)
          u---want to update an existing JAR file.



          文章來源:http://www.aygfsteel.com/supercrsky/articles/166271.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(150) | 評論 (0)編輯 收藏

          [導入]Java編譯器對于String常量表達式的優(yōu)化

           

          首先把問題擺出來,先看這個代碼

          String a = "ab";
                      String b = "a" + "b";
                      System.out.println((a == b));

          打印結(jié)果會是什么?類似這樣的問題,有人考過我,我也拿來考過別人(蠻好玩的,大家也可以拿來問人玩),一般答案會是以下幾種:

          1.true

          "a" + "b" 的結(jié)果就是"ab",這樣a,b都是"ab"了,內(nèi)容一樣所以"相等",結(jié)果true

          一般java新人如是答。

          2.false

          "a" + "a"會生成新的對象"aa",但是這個對象和String a = "ab";不同,(a == b)是比較對象引用,因此不相等,結(jié)果false

          對java的String有一定了解的通常這樣回答。

          3.true

          String a = "ab";創(chuàng)建了新的對象"ab"; 再執(zhí)行String b = "a" + "b";結(jié)果b="ab",這里沒有創(chuàng)建新的對象,而是從JVM字符串常量池中獲取之前已經(jīng)存在的"ab"對象。因此a,b具有對同一個string對象的引用,兩個引用相等,結(jié)果true.

          能回答出這個答案的,基本已經(jīng)是高手了,對java中的string機制比較了解。

          很遺憾,這個答案,是不夠準確的。或者說,根本沒有運行時計算b = "a" + "b";這個操作.實際上運行時只有String b = "ab";

          3的觀點適合解釋以下情況:

          String a = "ab";
                      String b = "ab";
                      System.out.println((a == b));

          如果String b = "a" + "b";是在運行期執(zhí)行,則3的觀點是無法解釋的。運行期的兩個string相加,會產(chǎn)生新的對象的。(本文后面對此有解釋)

          4.true

          下面是我的回答:編譯優(yōu)化+ 3的處理方式 = 最后的true

          String b = "a" + "b";編譯器將這個"a" + "b"作為常量表達式,在編譯時進行優(yōu)化,直接取結(jié)果"ab",這樣這個問題退化

          String a = "ab";
                      String b = "ab";
                      System.out.println((a == b));

          然后根據(jù)3的解釋,得到結(jié)果true

          這里有一個疑問就是String不是基本類型,像

          int secondsOfDay = 24 * 60 * 60;

          這樣的表達式是常量表達式,編譯器在編譯時直接計算容易理解,而"a" + "b" 這樣的表達式,string是對象不是基本類型,編譯器會把它當成常量表達式來優(yōu)化嗎?

          下面簡單證明我的推斷,首先編譯這個類:

          public class Test {
                      private String a = "aa";
                      }

          復制class文件備用,然后修改為

          public class Test {
                      private String a = "a" + "a";
                      }

          再次編譯,用ue之類的文本編輯器打開,察看二進制內(nèi)容,可以發(fā)現(xiàn),兩個class文件完全一致,連一個字節(jié)都不差.

          ok,真相大白了.根本不存在運行期的處理String b = "a" + "b";這樣的代碼的問題,編譯時就直接優(yōu)化掉了。

          下面進一步探討,什么樣的string + 表達式會被編譯器當成常量表達式?

          String b = "a" + "b";

          這個String + String被正式是ok的,那么string + 基本類型呢?

          String a = "a1";
                      String b = "a" + 1;
                      System.out.println((a == b)); //result = true
                      String a = "atrue";
                      String b = "a" + true;
                      System.out.println((a == b)); //result = true
                      String a = "a3.4";
                      String b = "a" + 3.4;
                      System.out.println((a == b)); //result = true

          可見編譯器對string + 基本類型是當成常量表達式直接求值來優(yōu)化的。

          再注意看這里的string都是"**"這樣的,我們換成變量來試試:

          String a = "ab";
                      String bb = "b";
                      String b = "a" + bb;
                      System.out.println((a == b)); //result = false

          這個好理解,"a" + bb中的bb是變量,不能進行優(yōu)化。這里很很好的解釋了為什么3的觀點不正確,如果String+String的操作是在運行時進行的,則會產(chǎn)生新的對象,而不是直接從jvm的string池中獲取。

          再修改一下,把bb作為常量變量:

          String a = "ab";
                      final String bb = "b";
                      String b = "a" + bb;
                      System.out.println((a == b)); //result = true

          竟然又是true,編譯器的優(yōu)化好厲害啊,呵呵,考慮下面這種情況:

          String a = "ab";
                      final String bb = getBB();
                      String b = "a" + bb;
                      System.out.println((a == b)); //result = false
                      private static String getBB() {
                      return "b";
                      }

          看來java(包括編譯器和jvm)對string的優(yōu)化,真的是到了極點了,string這個所謂的"對象",完全不可以看成一般的對象,java對string的處理近乎于基本類型,最大限度的優(yōu)化了幾乎能優(yōu)化的地方。

          另外感嘆一下,string的+號處理,算是java語言里面唯一的一個"運算符重載"(接觸過c++的人對這個不會陌生)吧?




          文章來源:http://www.aygfsteel.com/supercrsky/articles/166463.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(119) | 評論 (0)編輯 收藏

          [導入]Java,誤解為何如此之深

          前幾天被電話面試,問Java的參數(shù)傳遞方式,我說只有一種方式,就是by value啊,對方糾正我說,基本類型傳值,對象類 型傳引用;嗚呼,當時被噎了一下,幾秒鐘后回過神來,我明白他的意思,也明白我碰上新世紀的新新人類了,但我怕他不明白啊,就說我們還是先把“引用”這個 概念定義清楚吧,不要同一個詞兩人有兩個意思,或者舉個例子吧,在函數(shù)里對String類型的參數(shù)賦值是不影響實際參數(shù)的啊,于是他也明白我其實也明白, 電話面試就算過了
          然而還不算完,正式面試的四輪:筆試題,筆試完后與leader談,談完后與manager談,談完后與VP談,居然每一輪都有這道題!只不過換成了swap函數(shù)的形式,讓你說出執(zhí)行結(jié)果;我就納了悶了,這道題在人們心目中的形象就那么高大?并且甲方答案也似是而非?
          Bjarne一直認為是C++的教育害了C++,那么是什么害了Java語言呢?過度的商業(yè)宣傳!
          當然,商業(yè)宣傳成功的幫助了Java平臺,吸引了大量開發(fā)者,但對Java語言來說,先聽到宣傳詞后再來學習的初學者,耳中充斥的是“Java取消了指針”,“Java沒有內(nèi)存泄露”,“Java純面向?qū)ο?#8221;等宣傳用語,先入為主的就接受了表面現(xiàn)象,而沒有理解問題的實質(zhì)
          Java 取消了指針?看看那個所謂的“引用”為空時拋出的異常吧,看看在Java實現(xiàn)者的眼中這個東西到底是啥吧:NullPointerException!不 是我鄙視Sun,它的細節(jié)偽裝的確實不如MS:.Net里對應的異常叫NullReferenceException,雖然也是換湯不換藥;作為一種類C語言,我認為對應概念的命名還是一致較好,Java里其實全是指針,你基本無法得到對象本身,只不過這種指針功能受限,不需刪除而已
          指針的概念被偽裝起來,不需要delete了,那么除內(nèi)存之外的其它資源呢?數(shù)數(shù)你的程序里有多少個finally就可以了
          Java 純面向?qū)ο螅科鋵嵕瓦@句話本身來說也無可厚非,只是它使用了<<箭魚行動>>里定義的“錯誤引導”,這句話會使初學者傾向于認為 用Java寫出來的程序都是面向?qū)ο蟮模瑥亩璧K了理解真正的面向?qū)ο螅粩?shù)數(shù)你程序里有多少根據(jù)對象類型的switch/if/else就可以了
          題外話:
          面試時被問道面向?qū)ο蟮娜齻€基本特征,我知道他想聽到什么封裝繼承多態(tài),但實際上傳統(tǒng)面向?qū)ο蟮暮诵奶卣骶褪嵌鄳B(tài),繼承只是用來實現(xiàn)多態(tài)的一種手段,并非本質(zhì)特征;C語言沒有繼承,但照樣可以進行OO風格的編程



          文章來源:http://www.aygfsteel.com/supercrsky/articles/166793.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(66) | 評論 (0)編輯 收藏

          [導入]Java泛型編程快速入門

               摘要: JDK1.5 令我們期待很久,可是當他發(fā)布的時候卻更換版本號為5.0。這說明Java已經(jīng)有大幅度的變化。本文將講解JDK5.0支持的新功能-----Java的泛型. 1、Java泛型 其實Java的泛型就是創(chuàng)建一個用類型作為參數(shù)的類。就象我們寫類的方法一樣,方法是這樣的method(String str1,String str2 ),方法中參數(shù)str1、str2的值是可變的。而泛型也是一樣...  閱讀全文


          文章來源:http://www.aygfsteel.com/supercrsky/articles/169570.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(96) | 評論 (0)編輯 收藏

          [導入]Static和Final修飾類屬性變量及初始化

          1.static修飾一個屬性字段,那么這個屬性字段將成為類本身的資源,public修飾為共有的,可以在類的外部通過test.a來訪問此屬性;在類內(nèi)部任何地方可以使用.如果被修飾為private私有,那么只能在類內(nèi)部使用.


           

          public class Test{
          public static int a;
          private Test(){
          a
          =0;
          }

          }

           

           

          如果屬性被修飾為static靜態(tài)類資源,那么這個字段永遠只有一個,也就是說不管你new test()多少個類的對象,操作的永遠都只是屬于類的那一塊內(nèi)存資源.例如:


           

          Test t1=new Test();
          t1.a
          =10;
          Test t2
          =new Test();
          System.out.println(t1.a);
          System.out.println(t2.a);
          System.out.println(Test.a);

           

           

          結(jié)果是3個0


          2.final 用于聲明屬性,方法和類,分別表示屬性一旦被分配內(nèi)存空間就必須初始化并且以后不可變,方法一旦定義必須有實現(xiàn)代碼并且子類里不可被覆蓋,類一旦定義不能被定義為抽象類或是接口,因為不可被繼承。


          而你的代碼里對final修飾的屬性進行了修改,所以錯誤.


          3. 被final修飾而沒有被static修飾的類的屬性變量只能在兩種情況下初始化:


          a.在它被定義的時候,例:

           

           

          public class Test{
          public final int a=0;
          private Test(){
          }

          }

           

           

          b.在構(gòu)造函數(shù)里初始化,例:

           

           

          public class Test{
          public final int a;
          private Test(){
          a
          =0;
          }

          }


           

           

          4.同時被final和static修飾的類的屬性變量只能在兩種情況下初始化:


          a.在它被定義的時候,例:

           

           

          public class Test{
          public final int a=0;
          private Test(){
          }

          }


           

           

          b.在類的靜態(tài)塊里初始化,例:

           

           

          public class Test{
          public final int a;
          static{
          a
          =0;
          }

          }


           

           

          5.分析第三第四原因:


          第三條:當這個屬性被修飾為final,而非static的時候,它屬于類的實例對象的資源,當類被加載進內(nèi)存的時候這個屬性并沒有給其分配內(nèi)存空間,而只是定義了一個變量a,只有當類被實例化的時候這個屬性才被分配內(nèi)存空間,而實例化的時候同時執(zhí)行了構(gòu)造函數(shù),所以屬性被初始化了,也就符合了當它被分配內(nèi)存空間的時候就需要初始化,以后不再改變的條件.


          第四條:當類的屬性被同時被修飾為static和final的時候,他屬于類的資源,那么就是類在被加載進內(nèi)存的時候(也就是應用程序啟動的時候)就要已經(jīng)為此屬性分配了內(nèi)存,所以此時屬性已經(jīng)存在,它又被final修飾,所以必須在屬性定義了以后就給其初始化值.而構(gòu)造函數(shù)是在當類被實例化的時候才會執(zhí)行,所以用構(gòu)造函數(shù),這時候這個屬性沒有被初始化.程序就會報錯.而static塊是類被加載的時候執(zhí)行,且只執(zhí)行這一次,所以在static塊中可以被初始化.

           




          文章來源:http://www.aygfsteel.com/supercrsky/articles/169574.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(115) | 評論 (0)編輯 收藏

          [導入]用Java代碼構(gòu)建一個線程池

               摘要: 在現(xiàn)代的操作系統(tǒng)中,有一個很重要的概念――線程,幾乎所有目前流行的操作系統(tǒng)都支持線程,線程來源于操作系統(tǒng)中進程的概念,進程有自己的虛擬地址空間以及正文段、數(shù)據(jù)段及堆棧,而且各自占有不同的系統(tǒng)資源(例如文件、環(huán)境變量等等)。與此不同,線程不能單獨存在,它依附于進程,只能由進程派生。如果一個進程派生出了兩個線程,那這兩個線程共享此進程的全局變量和代碼段,但每個線程各擁有各自的堆棧,因此它們擁有各自的局...  閱讀全文


          文章來源:http://www.aygfsteel.com/supercrsky/articles/169582.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(70) | 評論 (0)編輯 收藏

          [導入]Javadoc的簡捷使用

          J2SE5中的javadoc.exe的命令行可選參數(shù)多達五十余個,其復雜性可想而知,是不是看著頭都大了呢?但通常情況下,我們不想那么麻煩!

          假設源代碼在 C:\src 目錄下,其中 com.liigo 是主包,其下可能有數(shù)十個子包,數(shù)百(千)個Java文件。目錄結(jié)構(gòu)大約是這樣的:

          - C:\
              | src\
                | com\
                  | liigo\

                     | ***

          怎么才能以最簡捷的方式生成所有的API文檔呢?

          c:\>
          c:\>cd src
          c:\src>javadoc -d doc -subpackages com.liigo

          這樣就搞定了,最終生成的API文檔位于 c:\src\doc 目錄(該目錄是由javadoc.exe自動生成的)。

          上面的用法利用了“當前目錄”和“相對路徑”,當然也可以用絕對路徑:

          ...>javadoc -d c:\doc -sourcepath c:\src -subpackages com.liigo

          最終生成的API文檔位于 c:\doc 目錄(該目錄同樣是由javadoc.exe自動生成的)。


          總結(jié)一下:

          我們只用到了javadoc的三個參數(shù): -d,-subpackages,-sourcepath,其中:

          參數(shù) 說明
          -d 指定API文檔的輸出目錄,默認是當前目錄。建議總是指定該參數(shù)。
          -sourcepath 指定源代碼路徑,默認是當前目錄。 此參數(shù)通常是必須的。
          -subpackages 以遞歸的方式處理各子包。關鍵參數(shù)!如果不使用本參數(shù),每次只能處理一個子包(或需手工列出所有子包)。


          注:以上示例要求 javadoc.exe 所在路徑位于系統(tǒng)環(huán)境變量“PATH”中。


          補充一點:

          使用參數(shù) -author 可以將作者信息(@author ***)導出到最終生成的API文檔中, -version 可以生成版本信息。如果是自己寫的一個包,千萬不要忘了用 -author 哦:)

          最終完整的命令行是:

          ...>javadoc -d c:\doc -sourcepath c:\src -subpackages com.liigo -author -version

          javadoc的命令行語法如下:

          javadoc [ options ] [ packagenames ] [ sourcefiles ] [ @files ]

          參數(shù)可以按照任意順序排列。下面分別就這些參數(shù)和相關的一些內(nèi)容進行說明:


          • Packagenames 包列表。這個選項可以是一系列的包名(用空格隔開),例如java.lang java.lang.reflect
            java.awt。不過,因為javadoc不遞歸作用于子包,不允許對包名使用通配符;所以你必須顯示地列出希望建立文檔的每一個包。
          • Sourcefiles 源文件列表。這個選項可以是一系列的源文件名(用空格隔開),可以使用通配符。javadoc允許四種源文件:類源代碼文件、包描述文件、總體概述文件、其他雜文件。

            ◇ 類源代碼文件:類或者接口的源代碼文件。

            ◇ 包描述文件:每一個包都可以有自己的包描述文件。包描述文件的名稱必須是"package.html",與包的.java文件放置在一起。包描述文件的內(nèi)容通常是使用HTML標記寫的文檔。javadoc執(zhí)行時將自動尋找包描述文件。如果找到,javadoc將首先對描述文件中<body></body>之間的內(nèi)容進行處理,然后把處理結(jié)果放到該包的Package
            Summary頁面中,最后把包描述文件的第一句(緊靠<body>)放到輸出的Overview summary頁面中,并在語句前面加上該包的包名。

            ◇ 總體概述文件:javadoc可以創(chuàng)建一個總體概述文件描述整個應用或者所有包。總體概述文件可以被任意命名,也可以放置到任意位置。-overview選項可以指示總體概述文件的路徑和名稱。總體概述文件的內(nèi)容是使用HTML標記寫的文檔。javadoc在執(zhí)行的時候,如果發(fā)現(xiàn)-overview選項,那么它將首先對文件中<body></body>之間的內(nèi)容進行處理;然后把處理后的結(jié)果放到輸出的Overview
            summary 頁面的底部;最后把總體概述文件中的第一句放到輸出的Overview summary頁面的頂部。

            ◇ 其他雜文件:這些文件通常是指與javadoc輸出的HTML文件相關的一些圖片文件、Java源代碼文件(.java)、Java程序(.class)、Java小程序(Applets)、HTML文件。這些文件必須放在doc-files目錄中。每一個包都可以有自己的doc-files目錄。舉個例子,你希望在java.awt.Button的HTML文檔中使用一幅按鈕的圖片(Button.gif)。首先,你必須把圖片文件放到C:\user\src\java\awt\doc-files\中;然后在Button.java文件中加入下面注釋

            /**

            * This button looks like this:

            * <img src="doc-files/Button.gif">

            */
          • @files 包含文件。為了簡化javadoc命令,你可以把需要建立文檔的文件名和包名放在一個或多個文本文件中。例如,為了簡化下面命令:

            javadoc -d apidoc com.mypackage1 com.mypackage2 com.mypackage3

            你可以建立一個名稱為mypackage.txt的文件,其內(nèi)容如下:

            com.mypackage1

            com.mypackage2

            com.mypackage3

            然后執(zhí)行下面命令即可:

            javadoc -d apidoc @mypackage.txt

          • options 命令行選項。javadoc使用doclets(doclets是指用doclet API編寫的程序。)來確定輸出的內(nèi)容和格式。命令行選項中一部分是可用于所有doclet的通用選項,一部分是由默認的標準doclet提供的專用的選項。下面對各自一些常用的選項分別進行介紹:

            通用選項:

            -1.1 生成具有javadoc 1.1版本生成的文檔的外觀和功能的文檔。不是所有的選項都可以用于-1.1選項,具體可以使用javadoc
            -1.1 -help察看。

            -help 顯示聯(lián)機幫助。

            -bootclasspath classpathlist 指定"根類"(通常是Java平臺自帶的一些類。例如java.awt.*等)的路徑。

            -sourcepath sourcepathlist 指定包的源文件搜索路徑。但是必須注意,只有在javadoc命令中指定了包名的時候才可以使用-sourcepath選項。如果指定了包名,而省略了-sourcepath,那么javadoc使用類路徑查找源文件。舉例說明:假定你打算為com.mypackage建立文檔,其源文件的位置是C:\user\src。那么你可以使用下面的命令:

            javadoc -sourcepath c:\user\src com.mypackage

            -classpath classpathlist 指定javadoc查找"引用類"的路徑。引用類是指帶文檔的類加上它們引用的任何類。javadoc將搜索指定路徑的所有子目錄。Classpathlist可以包含多個路徑(使用;隔開)。如果省略-classpath,則javadoc使用-sourcepath查找源文件和類文件。舉例說明:假定你打算為com.mypackage建立文檔,其源文件的位置是C:\user\src,包依賴C:\user\lib中的庫。那么你可以使用下面的命令:

            javadoc -classpath c:\user\lib -sourcepath c:\user\src com.mypackage

            -overview path\filename 告訴javadoc從path\filename所指定的文件中獲取概述文檔,并且把它放到輸出的概述頁面(overview-summary.html)中。其中path\filename是相對于-sourcepath的相對路徑。

            -public 只顯示公共類以及成員。

            -protected 只顯示受保護的和公共的類以及成員。缺省選項。

            -package只顯示包、受保護的和公共的類以及成員。

            -private 顯示所有類和成員。

            -doclet class 指定javadoc產(chǎn)生輸出內(nèi)容的自定義doclet類。如果忽略這個選項,javadoc將使用默認的doclet產(chǎn)生一系列HTML文檔。

            -docletpath classpathlist 與- doclet選項相關,制定自定義的doclet類文件的路徑。Classpathlist可以包含多條路徑(用;隔開)。

            -verbose 在javadoc運行時提供更詳細的信息。

            標準doclet專用選項:

            -author 在生成的文檔中包含"作者"項。

            - d directory 指定javadoc保存生成的HTML文件的目錄。省略該選項將把文件保存在當前目錄。Directory可以是絕對目錄,也可以是相對當前目錄的相對目錄。

            -version 在生成的文檔中包含"版本"項。

            -use 為類和包生成"use"(用法)頁面。這些頁面描述了該類和包在javadoc命令涉及的文件中被使用的情況。例如:對于給定的類C,在C的用法頁面中將包含C的子類,類型為C的域,返回變量類型為C的方法以及在參數(shù)中有變量類型為C的方法和構(gòu)造器。

            -splitindex 把索引文件按照字母順序分為多個文件。每一個文件對應一個字母。

            -windowtitle title 指定輸出的HTML文檔的標題。

            -header header 指定輸出的HTML文檔的頁眉文本。

            -footer footer 指定輸出的HTML文檔的腳注文本。

            -bottom text 指定輸出的HTML文檔底部的文本。

            - group groupheading packagepatten;packagepatten;… 在總體概述頁面中按照命令的指定方式分隔各個包。例如執(zhí)行下面命令:

            javadoc -group "Core Packages" "java.lang*:java.util"

            -group "Extension Packages" "javax.*"

            java.lang java.lang.reflect java.util javax.servlet java.new

            在頁面中將有如下結(jié)果:

            Core Packages

            java.lang

            java.lang.reflect

            java.util

            Extension Packages

            javax.servlet

            Other Packages

            java.new

            ◇ - noindex 不輸出索引文件。

            ◇ - help 在文件的導航條中忽略help鏈接。

            ◇ - helpfile path\filename 指定導航條中的help鏈接所指向的幫助文件。忽略該選項,javadoc將生成缺省的幫助文件。

            ◇ -stylesheetfile path\filename 指定javadoc的HTML樣式表文件的路徑。忽略該選項,javadoc將自動產(chǎn)生一個樣式表文件stylesheet.css。

            通過上面的介紹,我們了解了javadoc的命令行語法,下面開始介紹javadoc文檔注釋方法。

            javadoc注釋以"/**"開始,以"*/"結(jié)束,里面可以包含普通文本、HTML標記和javadoc標記。javadoc只處理源文件中在類/接口定義、方法、域、構(gòu)造器之前的注釋,忽略位于其他地方的注釋。舉例如下:
            /**

            *我的第一個程序--<b>Helloworld</b>

            *@author 王鴻

            *@version 1.0 2001/10/15

            */

            public class myHelloworld

            {

            /**

            *在main( )方法中使用的顯示用字符串

            *@see #main(java.lang.String[])

            */

            static String SDisp

            使用下面命令:

            javadoc -private -d doc -author -version myHelloworld.java

            即可以生成漂亮的關于myHelloworld.java的API文檔了。

            上面例子中以@開頭的標記就是javadoc標記。在Java程序中正確使用javadoc標記是一個良好的注釋習慣,將非常有助于javadoc自動從源代碼文件生成完整的格式化API文檔。下面就對各種標記進行詳細說明。

            @author name-text 指定生成文檔中的"作者"項,從JDK/SDK 1.0開始引入。name-text可以指定多個名字(使用","隔開)。文檔注釋可以包含多個類。

            {@docroot} 代表產(chǎn)生文檔的根路徑,從JDK/SDK 1.3開始引入。用法舉例如下

            /**

            *see the <a href={@docroot}/copyright.html>copyright</a>

            */

            假定生成文檔的根目錄是doc,上面注釋所在的文件最后生成的文件是doc\utility\utl.html,那么"copyright"的鏈接會指向..\copyright.html。

            @deprecated deprecated-text 添加注釋,表明不推薦使用該API。

            @exception class-name description @throw的同義標記,從JDK/SDK 1.0開始引入。

            {@link package.class#member label} 插入指向package.class#member的內(nèi)嵌鏈接,從JDK/SDK
            1.2開始引入。舉例說明,假定注釋中有如下文檔:

            /** Use the {@link #getComponentAt(int, int) getComponentAt} method. */

            那么javadoc最終生成的HTML頁面中將有如下內(nèi)容

            Use the <a href = "Component.html#getComponentAt(int,int)"
            > getComponentAt </a> method.

            @param parameter-name description 描述參數(shù),從JDK/SDK 1.0開始引入。

            @return description 描述返回值,從JDK/SDK 1.0開始引入。

            @see reference 添加"參見"標題,其中有指向reference的鏈接或者文本項,從JDK/SDK
            1.0開始引入。@see標記有三種形式,下面分別說明:

            (1)、@see "string" 為"string"添加文本項,不產(chǎn)生鏈接。

            (2)、@see <a href="URL#Value">Label</a> 使用HTML標記產(chǎn)生鏈接

            (3)、@see package.class#member Label 使用Java語言的名字package.class #member產(chǎn)生鏈接。

            ◇ @serial field-description 用于缺省可序列化域的注釋,從JDK/SDK 1.2開始引入。

            ◇ @serialField field-name field-type field-description 建立Serializable類的serialPersistentFields成員的ObjectStreamField組件的文檔,從JDK/SDK
            1.2開始引入。

            @serialData data-description data-description建立數(shù)據(jù)序列和類型的文檔,從JDK/SDK
            1.2開始引入。

            @since since-text 利用since-text內(nèi)容為文檔增加"since"標題,從JDK/SDK
            1.1開始引入。

            @throws class-name description 與@exception同義。用class-name和description為輸出文檔添加"拋出"標題,從JDK/SDK
            1.2開始引入。

            @version version-text 添加"版權(quán)"標題,從JDK/SDK 1.0開始引入。

            上面介紹了標準doclet提供的所有標記。不過,需要注意這些標記的使用是有位置限制的。其中可以出現(xiàn)在類或者接口文檔注釋中的標記有:@see、{@link}、@since、@deprecated、@author、@version。可以出現(xiàn)在方法或者構(gòu)造器文檔注釋中的標記有:@see、{@link}、@since、@deprecated、@param、@return、@throws、@exception、@serialData。可以出現(xiàn)在域文檔注釋中的有:@see、{@link}、@since、@desprecated、@serial、@serialField。

            除了javadoc自身提供的標準標記以外,我們可以定制自己的標記嗎?當然可以。只需要對javadoc標準的doclet程序進行擴充即可。實際上,利用javadoc提供的doclet
            API,不僅可以擴充doclet標記,甚至還可以改變javadoc的整個輸出。為了滿足需要,你可以使javadoc輸出普通文本、XML文件等。由于擴充doclet涉及到Java編程,本文不再做深入介紹。

            總之,javadoc提供了完整規(guī)范的API文檔功能。在軟件項目管理中,合理地使用javadoc不僅可以減少
            開發(fā)時的文檔工作量,提高效率;而且還非常有利于將來軟件的修改和維護。





          文章來源:http://www.aygfsteel.com/supercrsky/articles/172385.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(251) | 評論 (0)編輯 收藏

          [導入]throws和throw的區(qū)別

          這兩者雖然看起來只有一個s的區(qū)別,但是作用完全不一樣。
                                                                                             
          /////java處理異常方式///////////////////////////////

               在java代碼中如果發(fā)生異常的話,jvm會拋出異常對象,導致程序代碼中斷,這個時候jvm在做的操作就是:創(chuàng)建異常對象,然后拋出,比如:

           

          int i= 1; 
          int j = 0
          ; 
          int res = 0
          ; 
          res 
          = i/j;//除0錯誤 

          System.out.println(res); 

           

          這5句代碼運行到第四句會中斷,因為jvm拋出了異常
           
          ////throw的作用/////////////////////////////////////////
          手動拋出異常

          但是有時候有些錯誤在jvm看來不是錯誤,比如說

          int age = 0
          age 
          = -100

          System.out.println(age); 

           

              很正常的整形變量賦值,但是在我們眼中看來就不正常,誰的年齡會是負的呢。 所以我們需要自己手動引發(fā)異常,這就是throw的作用。

          int age = 0
          age 
          = -100

          if(age<0


             Exception e 
          = new Exception("throw exception");//創(chuàng)建異常對象 

             throw e;//拋出異常 
          }
           
          System.out.println(age); 

           

          ////throws的作用///////////////////////////////////
          聲明方法可能回避的異常

             有異常被拋出了,就要做處理,所以java中有try-catch。可是有時候一個方法中產(chǎn)生了異常,但是不知道該怎么處理它,那么就放著不管,當有異常拋出時會中斷該方法,而異常被拋到這個方法的調(diào)用者那里。這個有點像下屬處理不了的問題就交到上司手里一樣,這種情況稱為回避異常。

             但是這使得調(diào)用這個方法就有了危險,因為誰也不知道這個方法什么時候會丟一個什么樣的異常給調(diào)用者,所以在定義方法時,就需要在方法頭部分使用throws來聲明這個方法可能回避的異常。

          void fun()throws IOException,SQLException 

           
          }
           

           

          這表示 fun方法可能會丟兩個異常出來,那么在調(diào)用fun的時候就會做好準備,比如可以這樣

          try
             fun(); 
          }
          catch(IOException e) { }

          catch(SQLException e) { } 

           

           




          文章來源:http://www.aygfsteel.com/supercrsky/articles/176511.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(113) | 評論 (0)編輯 收藏

          [導入]Eclipse和MyEclipse工程描述符詳解

             有時候在一個Java工程里我們需要加入第三方jar包,這時你加入的最好相對路徑,
          而不是絕對路徑。否則你的工程拿到別處就不行運行了。意思就是說你最好把相關的jar放到工程目錄下。對于Web工程來說相對簡單,web工程是有個lib 目錄的。直接復制到這里就行了。而非web工程是不可以的。Eclispe是不能自動完成導入copy的。
          這就需要我們手動配置,對于工作描述文件,Eclipse和MyEclpse全是用xml來描述的。

          現(xiàn)在我們來看看Eclipse的.classpath文件:

          <?xml version="1.0" encoding="UTF-8"?>
          <classpath>
              
          <!-- 源碼目錄 -->
              
          <classpathentry kind="src" path="src"/>
              
          <!-- JDK運行時容器 -->
              
          <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
              
          <!-- 以下為類庫 path為你自定義的目錄 -->
              
          <classpathentry kind="lib" path="lib/swing-layout-1.0.3.jar"/>
              
          <classpathentry kind="lib" path="lib/AbsoluteLayout.jar"/>
              
          <classpathentry kind="lib" path="lib/jtds-1.2.2.jar"/>
              
          <classpathentry kind="lib" path="lib/jxl.jar"/>
              
          <!-- 編譯后輸出class 目錄  -->
              
          <classpathentry kind="output" path="bin"/>
          </classpath>


          在xml中我已經(jīng)加了注釋。想你也明白了吧。

          .project文件:
          <?xml version="1.0" encoding="UTF-8"?>
          <projectDescription>
              
          <!-- 工程名稱 -->
              
          <name>execlInterface</name>
              
          <comment></comment>
              
          <projects></projects>
              
          <!-- 編譯器指定 -->
              
          <buildSpec>
                  
          <buildCommand>
                      
          <name>org.eclipse.jdt.core.javabuilder</name>
                      
          <arguments></arguments>
                  
          </buildCommand>
              
          </buildSpec>
              
          <!-- 核心特性 -->
              
          <natures>
                  
          <nature>org.eclipse.jdt.core.javanature</nature>
              
          </natures>
          </projectDescription>


          對于myeclipse工程多了一個.mymetadata文件:
          <?xml version="1.0" encoding="UTF-8"?>
          <!-- 
              type : 工程類型
              name : 工程名稱
              id   : 工程在工作空間內(nèi)的唯一標識
              context-root : 網(wǎng)站根路徑
              j2ee-spec: J2EE標準
              archive : 打包后war文件
           
          -->

          <project-module
            
          type="WEB"
            name
          ="upload"
            id
          ="myeclipse.1152954865843"
            context-root
          ="/upload"
            j2ee-spec
          ="1.4"
            archive
          ="upload.war">
            
          <attributes>
            
          <!-- value : Web根目錄名稱 -->
              
          <attribute name="webrootdir" value="WebRoot" />
            
          </attributes>
          </project-module>




          文章來源:http://www.aygfsteel.com/supercrsky/articles/204013.html

          posted @ 2009-04-10 13:20 天天開源 閱讀(863) | 評論 (0)編輯 收藏

          僅列出標題
          共2頁: 上一頁 1 2 
          主站蜘蛛池模板: 绍兴市| 临西县| 南靖县| 阿克苏市| 泾源县| 仁怀市| 安义县| 靖安县| 香格里拉县| 铁岭市| 蕲春县| 临高县| 黄龙县| 余庆县| 砚山县| 礼泉县| 新龙县| 仁怀市| 彭泽县| 集安市| 临汾市| 成安县| 南投市| 陇川县| 云和县| 东丽区| 水富县| 江山市| 财经| 石城县| 民乐县| 洪江市| 尚义县| 潢川县| 娱乐| 正定县| 张家口市| 洞头县| 枝江市| 富民县| 屯留县|