<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    飛翔的起點

    從這里出發

    導航

    <2008年9月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011

    統計

    常用鏈接

    留言簿(5)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    2008年9月9日 #

    Queue

    public class QuenDemo {
      public static void main(String[] args){
       //public class Queue extends Collection
       Queue<Integer> queue=new LinkedList<Integer>();
       Random  rand = new Random(47);
       for(int i=0;i<10;i++){
        queue.offer(rand.nextInt(i+10));
       }
       System.out.println("1111"+queue.toString());
       printQ(queue);
       //public class LinkedList extends AbstractSequentialList implements List,Queue,Cloneable,Serializable
       Queue<Character> qc=new LinkedList<Character>();
       for(char c:"guoxzh".toCharArray()){
        qc.offer(c);
        System.out.println("qc=="+qc.toString());
       }
        printQ(qc);
      }
      
      public static void printQ(Queue queue){
       while(queue.peek()!=null){
        //peek和element都是在不移除的情況下返回對頭,但是peek在隊列為空的情況下返回null,element方法會拋出NoSuchElementException異常
        System.out.println(queue.remove());
        //remove和poll方法都是在移除并返回對頭,但是poll在為空時返回null,而remove會拋出NoSucheElementException異常
        System.out.println("2222"+queue.toString());
       }
      }
    }

    posted @ 2009-10-18 18:29 forgood 閱讀(211) | 評論 (0)編輯 收藏

    java中的編碼方法

    package src;

    import java.io.UnsupportedEncodingException;

    public class ChangeCharset {
      /** 7位ASCII字符,也叫作ISO646-US、Unicode字符集的基本拉丁塊 */
      public static final String US_ASCII = "US-ASCII";

      /** ISO 拉丁字母表 No.1,也叫作 ISO-LATIN-1 */
      public static final String ISO_8859_1 = "ISO-8859-1";

      /** 8 位 UCS 轉換格式 */
      public static final String UTF_8 = "UTF-8";

      /** 16 位 UCS 轉換格式,Big Endian(最低地址存放高位字節)字節順序 */
      public static final String UTF_16BE = "UTF-16BE";

      /** 16 位 UCS 轉換格式,Little-endian(最高地址存放低位字節)字節順序 */
      public static final String UTF_16LE = "UTF-16LE";

      /** 16 位 UCS 轉換格式,字節順序由可選的字節順序標記來標識 */
      public static final String UTF_16 = "UTF-16";

      /** 中文超大字符集 */
      public static final String GBK = "GBK";

      /**
       * 將字符編碼轉換成US-ASCII碼
       */
      public String toASCII(String str) throws UnsupportedEncodingException{
       return this.changeCharset(str, US_ASCII);
      }
      /**
       * 將字符編碼轉換成ISO-8859-1碼
       */
      public String toISO_8859_1(String str) throws UnsupportedEncodingException{
       return this.changeCharset(str, ISO_8859_1);
      }
      /**
       * 將字符編碼轉換成UTF-8碼
       */
      public String toUTF_8(String str) throws UnsupportedEncodingException{
       return this.changeCharset(str, UTF_8);
      }
      /**
       * 將字符編碼轉換成UTF-16BE碼
       */
      public String toUTF_16BE(String str) throws UnsupportedEncodingException{
       return this.changeCharset(str, UTF_16BE);
      }
      /**
       * 將字符編碼轉換成UTF-16LE碼
       */
      public String toUTF_16LE(String str) throws UnsupportedEncodingException{
       return this.changeCharset(str, UTF_16LE);
      }
      /**
       * 將字符編碼轉換成UTF-16碼
       */
      public String toUTF_16(String str) throws UnsupportedEncodingException{
       return this.changeCharset(str, UTF_16);
      }
      /**
       * 將字符編碼轉換成GBK碼
       */
      public String toGBK(String str) throws UnsupportedEncodingException{
       return this.changeCharset(str, GBK);
      }
     
      /**
       * 字符串編碼轉換的實現方法
       * @param str  待轉換編碼的字符串
       * @param newCharset 目標編碼
       * @return
       * @throws UnsupportedEncodingException
       */
      public String changeCharset(String str, String newCharset)
        throws UnsupportedEncodingException {
       if (str != null) {
        //用默認字符編碼解碼字符串。
        byte[] bs = str.getBytes();
        //用新的字符編碼生成字符串
        return new String(bs, newCharset);
       }
       return null;
      }
      /**
       * 字符串編碼轉換的實現方法
       * @param str  待轉換編碼的字符串
       * @param oldCharset 原編碼
       * @param newCharset 目標編碼
       * @return
       * @throws UnsupportedEncodingException
       */
      public String changeCharset(String str, String oldCharset, String newCharset)
        throws UnsupportedEncodingException {
       if (str != null) {
        //用舊的字符編碼解碼字符串。解碼可能會出現異常。
        byte[] bs = str.getBytes(oldCharset);
        //用新的字符編碼生成字符串
        return new String(bs, newCharset);
       }
       return null;
      }

      public static void main(String[] args) throws UnsupportedEncodingException {
       ChangeCharset test = new ChangeCharset();
       String str = "This is a 中文的 String!";
       System.out.println("str: " + str);
       String gbk = test.toGBK(str);
       System.out.println("轉換成GBK碼: " + gbk);
       System.out.println();
       String ascii = test.toASCII(str);
       System.out.println("轉換成US-ASCII碼: " + ascii);
       gbk = test.changeCharset(ascii,ChangeCharset.US_ASCII, ChangeCharset.GBK);
       System.out.println("再把ASCII碼的字符串轉換成GBK碼: " + gbk);
       System.out.println();
       String iso88591 = test.toISO_8859_1(str);
       System.out.println("轉換成ISO-8859-1碼: " + iso88591);
       gbk = test.changeCharset(iso88591,ChangeCharset.ISO_8859_1, ChangeCharset.GBK);
       System.out.println("再把ISO-8859-1碼的字符串轉換成GBK碼: " + gbk);
       System.out.println();
       String utf8 = test.toUTF_8(str);
       System.out.println("轉換成UTF-8碼: " + utf8);
       gbk = test.changeCharset(utf8,ChangeCharset.UTF_8, ChangeCharset.GBK);
       System.out.println("再把UTF-8碼的字符串轉換成GBK碼: " + gbk);
       System.out.println();
       String utf16be = test.toUTF_16BE(str);
       System.out.println("轉換成UTF-16BE碼:" + utf16be);
       gbk = test.changeCharset(utf16be,ChangeCharset.UTF_16BE, ChangeCharset.GBK);
       System.out.println("再把UTF-16BE碼的字符串轉換成GBK碼: " + gbk);
      }
    }

    posted @ 2009-09-23 14:25 forgood 閱讀(300) | 評論 (0)編輯 收藏

    byte數組和String之間的轉化

    JAVA里面關于byte數組和String之間的轉換問題

    把byte轉化成string,必須經過編碼

    例如下面一個例子:

    import java.io.UnsupportedEncodingException;

    public class test{
     public static void main(String g[]) {
      String s = "12345abcd";
      byte b[] = s.getBytes();
      String t = b.toString();

      System.out.println(t);

     }
    }
    輸出字符串的結果和字符串s不一樣了.

    經過以下方式轉碼就可以正確轉換了:

    public class test{
     public static void main(String g[]) {
      String s = "12345abcd";
      byte b[] = s.getBytes();
      try {
       String t = new String(b);
       System.out.print(t);
      } catch (Exception e) {
       e.printStackTrace();
      }
     }
    }

    引用:
    String   str   =   "String"; 
              byte[]   byte1   =   str.getBytes(); 
              String   str1   =   new   String(byte1); 
              byte[]   byte2   =   str1.getBytes(); 
              String   str2   =   new   String(byte2); 
              System.out.println("str<<<"   +   str); 
              System.out.println("byte1<<<"   +   byte1); 
              System.out.println("str1<<<"   +   str1); 
              System.out.println("byte2<<<"   +   byte2); 
              System.out.println("str2<<<"   +   str2); 
      ------------------------------------- 
      輸出結果 
      str<<<String 
      byte1<<<[B@192d342 
      str1<<<String 
      byte2<<<[B@6b97fd 
      str2<<<String 
      
      想請教為什么兩個byte輸出的不一樣呢? 
     

    String   str   =   "String"; 
              byte[]   byte1   =   str.getBytes(); 
              String   str1   =   new   String(byte1); 
              byte[]   byte2   =   str1.getBytes(); 
      ---------- 
      注意byte1是str得到的byte數組,而byte2是另一個字符串str1得到的數組 
      他們本身也是兩個對象  
       
      直接打印實際上調用的是toString()方法,而toString()的默認實現是打印對象類型+hashCode()  
      [B表示byte數組  @表示之后的是地址  后面跟著的是hashCode,其實就是其虛擬機地址  
      

    posted @ 2009-09-23 14:19 forgood 閱讀(3072) | 評論 (0)編輯 收藏

    jvm的內存模型

    從大的方面來講,JVM的內存模型分為兩大塊:

     

    永久區內存( Permanent space)和堆內存(heap space)。

     

    棧內存(stack space)一般都不歸在JVM內存模型中,因為棧內存屬于線程級別。

    每個線程都有個獨立的棧內存空間。

     

    Permanent space里存放加載的Class類級對象如class本身,methodfield等等。

    heap space主要存放對象實例和數組。

    heap spaceOld GenerationNewGeneration組成,OldGeneration存放生命周期長久的實例對象,而新的對象實例一般放在NewGeneration

    New Generation還可以再分為Eden(圣經中的伊甸園)、和Survivor區,新的對象實例總是首先放在Eden區,Survivor區作為Eden區和Old區的緩沖,可以向Old區轉移活動的對象實例。

     

    一般,我們常見的OOMout of memory)內存溢出異常,就是堆內存空間不足以存放新對象實例時導致。

     

    永久區內存溢出相對少見,一般是由于需要加載海量的Class數據,超過了非堆內存的容量導致。通常出現在Web應用剛剛啟動時,因此Web應用推薦使用預加載機制,方便在部署時就發現并解決該問題。

     

    棧內存也會溢出,但是更加少見。

     

    堆內存優化:

    調整JVM啟動參數-Xms  -Xmx   -XX:newSize -XX:MaxNewSize,如調整初始堆內存和最大對內存 -Xms256M -Xmx512M。 或者調整初始New Generation的初始內存和最大內存-XX:newSize=128M -XX:MaxNewSize=128M

     

    永久區內存優化:

    調整PermSize參數   如  -XX:PermSize=256M-XX:MaxPermSize=512M

     

    棧內存優化:

    調整每個線程的棧內存容量  如  -Xss2048K

     

     

    最終,一個運行中的JVM所占的內存堆內存  +  永久區內存  +  所有線程所占的棧內存總和 

    posted @ 2009-09-18 09:12 forgood 閱讀(296) | 評論 (0)編輯 收藏

    財務公司概述

    財務公司的背景:

    財務公司有兩種模式:

    1.美國模式財務公司是以搞活商品流通、促進商品銷售為特色的非銀行金融機構,它依附于制造商,是一些大型耐用品而設立的受控子公司,這類財務公司主要是為零售商提供融資服務的,主要分布在美國、加拿大和德國。

    2.英國模式財務公司基本上依附于商業銀行,其組建的目的在于規避政府對商業銀行的監管,因為政府規定,商業銀行不得從事證券投資業務,而財務公司不屬于銀行,所以不受此限制,這種模式主要分布在英國、日本和中國香港。

    中國財務公司概況

    財務公司又稱金融公司,是為了企業技術改造,新產品開發及產品銷售提供金融服務的,以中長期金融業務為主的非銀行機構,各國的名稱不同,業務內容也不一樣。

    財務公司是中國企業體制改革和融資體制改革的產物,國家為了增強國有大中型企業的活力,盤活企業內部資金,增強企業集團的融資能力,支持企業集團的發展,促進產業結構和產品結果的調整,以及探索具有中國特色的產品資本與金融資本相結合的道路,于1987年成立了中國第一家企業集團財務公司,即東風汽車工業集團財務公司。

    財務公司---公司主體

    財務公司是根據《公司法》和《企業集團財務公司管理辦法》設立的,為企業集團成員單位技術改造、新產品開發及產品銷售提供金融服務,以中長期金融業務為主的非銀行機構。

    財務公司一般分企業附屬財務公司和非企業附屬財務公司,企業附屬財務公司由企業設立,為本企業服務,但是服務范圍不僅局限于本企業;非企業附屬財務公司包括銀行附屬財務公司、引起合資財務公司和獨立財務公司。

    1.銀行附屬財務公司是由銀行控股,因規避監管、實現金融創新和彌補銀行的不足而設立的,同時也為企業和個人提供金融服務。

    2.銀行合資財務公司是銀行和企業出于金融創新規避監管或促進產融合作的考慮而設立,為企業和個人提供金融服務,

    3.獨立財務公司一般是沒有母公司的財務公司,規模較小,比較靈活,在某一方面提供融資服務。

    財務公司的業務范圍

    1.經中國人民銀行批準,中國財務公司可從事下列部分或全部業務:

    2.吸收成員單位3個月以上定期存款。
    3.發行財務公司債券
    4.同業拆借
    5.對成員單位辦理貸款及融資租賃。
    6.辦理集團成員單位產品的消費信貸買方信貸融資租賃
    7.辦理成員單位商業匯票的承兌及貼現
    8.辦理成員單位的委托貸款及委托投資
    9.有價證券、金融機構股權及成員單位股權投資。
    10.承銷成員單位的企業債券
    11.對成員單位辦理財務顧問、信用鑒證及其他咨詢代理業務。
    12.對成員單位提供擔保。
    13.境外外匯借款。
    14.中國人民銀行批準的其他業務。

    財務公司的主要作用

    1.業務范圍比較廣,但是以企業集團為限。

    主要業務有存款、貸款、結算、擔保和代理等一般銀行業務,還可以經人民銀行批準,開展證券、信托投資等業務。

    2.資金來源于集團公司,用于集團公司,對集團公司的依附性強,

    財務公司的資金主要來源于兩個方面:a、集團公司和集團成員公司投入的資本金;b、集團公司成員企業在財務公司的存款。

    3.接受企業集團和人民銀行的雙重監管。

    財務公司是企業內部的金融機構,期股東大都是集團公司成員企業,因而其景榮活動必然受到集團公司的監督,同時,財務公司所從事的是金融業務,其金融活動必須接受人民銀行監管

    4.堅持服務與效益相結合、服務優先的經營原則。雖然財務公司作為獨立的法人,但是是企業集團內部的機構,且集團公司成員企業大都是財務公司的股東,所以財務公司在經營中一般都應較好地處理服務與效益的關系,在堅持為集團公司成員企業提供良好金融服務的前提下,努力實現利潤的最大化,

    財務公司的作用

    1.在資金管理方面和使用上,促使企業從粗放型向集約型轉變,

    沒有財務公司之前,集團公司成員企業不能直接發生信貸關系,有些單位資金閑置,有些單位資金緊張,財務公司成立以后,成員單位成為財務公司的股東,在一定程度上集中了各成員單位的資本來進行一體化經營,財務公司應用金融手段將集團公司內企業的閑散資金集中起來,統籌安排使用,這樣不僅可以加快集團成員企業間資金結算的速度,而且總整體上降低了集團財務費用,提高就然公司資金的使用效率,加速集團公司資產一體化經營的進程,

    2.財務公司以資金為紐帶,以服務為手段,增強了集團公司的凝聚力。

    股本金將成員單位聯接在一起,另一方面財務公司吸納的資金又成為集團公司企業信貸資金的一個來源,從而集團公司成員企業進一步緊密的聯結在一起,形成了一種相互支持,相互促進,共同發展的局面。

    3.及時解決了企業集團急需的資金,保證企業生產經營的正常進行。

    4.增強了企業集團的融資功能,促進了集團公司的發展壯大,

    5.有利于打破現有銀行體制資金規模按行政區域分割的局面,促進大集團公司跨地域、跨行業發展,

    6.促進了金融業的競爭,有利于金融機構提高服務質量和效益,有利于金融體制改革的深化。

    posted @ 2009-09-06 16:19 forgood 閱讀(227) | 評論 (0)編輯 收藏

    英語常用語

     1、“我請客”:覺得我們常用pay這個詞,如Let me pay it for you。這里列舉三種說法:I am buying;This is on me;This is all my bill。

      2、“收買某人”:有個比較正式的詞叫bribe,名詞時為“賄賂”的意思,動詞時就有“收買”之意。既然提到了“買”,那么我們能不能用上buy呢?當然,那就是buy sb off。

      3、“向前看!”:我們會說Look forward!而美語里有個更貼切的說法是Eyes front!“眼睛朝前”,是不是很生動?

      4、“頭等大事”:你會怎么翻譯呢?The most important thing嗎?看這個吧“It's on the top of my list”。

      5、“看在主的份上,你就……”:兩種說法,其一是For the love of God,另外For God's sake(sake的意思是緣故、關系)二者之中,后者更常用

      6、“我不是傻子!”:I am not a fool?對,語法完全正確。但再看這個I am no fool。比上面的只少兩個字母,但是不是感覺不一樣?同樣的道理,我們常說I have no idea,而不常說I dont have any idea。

      7、short hairs:是說“短頭發”嗎?呵呵,它就是我們說的“小辮子”!

      8、one-time thing:帥哥跟一美女過了一夜,回來后室友問帥哥:Do you really love her?帥哥回答:Oh, it was just a one-time thing!那么one-time thing是什么呢?我就不羅嗦嘍!

      9、She knew red was her color。“她知道紅色是她的顏色”?恰當的翻譯是:她知道自己和紅色很相配。Then, what's your color?

      10、“停電”:No electricity?恩,夠直白!其實提到“電”,老外更多是用power,停電就可以是Ther is a power failure或Power goes out

    posted @ 2009-08-30 12:49 forgood 閱讀(230) | 評論 (0)編輯 收藏

    html中的標簽

    有一次編網頁的時候,把base 標簽給刪掉了,超鏈接怎么也行不通,老是路徑不對,原來是base 標簽在做怪:
           <base>標記定義了文檔的基礎URL地址,在文檔中所有的相對地址形式的URL都是相對于這里定義的URL而言的。一篇文檔中的<base>標記不能多于一個,必須放于頭部,并且應該在任何包含URL地址的語句之前。
          (1)href 屬性
           href屬性指定了文檔的基礎URL地址,該屬性在<base>標記中是必須存在的。
    例如:如果希望將文檔的基礎URL定義為“www.abc.com”,則可以使用如下語句:
    <base href = "www.abc.com"> 當定義了基礎URL地址之后,文檔中所有引用的URL地址都從該基礎URL地址開始,例如,對于上面的語句,如果文檔中一個超級鏈接指向gsl/welcome.htm,則它實際上指向的是如下URL地址:www.abc.com/gsl/welcome.htm
           (2)target
            target屬性同框架一起使用,它定義了當文檔中的鏈接被點擊后,在哪一個框架中展開頁面。如果文檔中超級鏈接沒有明確指定展開頁面的目標框架集,則就使用這里定義的地址代替。常用的target的屬性值有:
            _blank,表明在新窗口中打開鏈接指向的頁面。
            _self,在當前文檔的框架中打開頁面。
            _parent,在當前文檔的父窗口中打開頁面。
            _top,在鏈接所在的完整窗口中展開頁面。

    posted @ 2009-08-26 11:12 forgood 閱讀(190) | 評論 (0)編輯 收藏

    改變原虛擬硬盤的大小

    1、增加一個虛似硬盤

        如果是在vmware里面安裝的windows系統,添加個硬盤很容易,

    (1)先打開要添加硬盤的虛擬系統(不要啟動該系統),選擇虛擬機菜單---設置-----選添加,

    (2)然后在彈出添加硬件向導窗口中------選擇硬盤-------一路next就好了,后面的操作和新建一個虛擬機的時候配置硬盤是一樣的。

    (3)添加了新的硬盤后,啟動windows進到系統中,在控制面板中找“管理工具”->“計算機管理”,然后選“磁盤管理”,添加新磁盤就好了。

    其實很簡單的..如果想繼續給VMware增加硬盤的話,重復上述動作。

    2、改變原虛擬硬盤的大小

    界面中并沒有提供增加硬盤容量的方法。

    只能在命令行形式下執行。

    安裝所在盤的c:\Program Files\VMware\VMware Workstation下有一個vmware-vdiskmanager.exe,就是它。

    命令參數如下:
    ------------------------------------------------------------------
    Usage: vmware-vdiskmanager.exe OPTIONS <disk-name> | <mount-point>

    Offline disk manipulation utility

       Options:
          -c                    : create disk; need to specify other create options
          -d                    : defragment the specified virtual disk
          -k                    : shrink the specified virtual disk
          -n <source-disk>      : rename the specified virtual disk; need to
                                 specify destination disk-name
          -p                    : prepare the mounted virtual disk specified by
                                 the drive-letter for shrinking
          -q                    : do not log messages
          -r <source-disk>      : convert the specified disk; need to specify
                                 destination disk-type
          -x <new-capacity>     : expand the disk to the specified capacity

          Additional options for create and convert:
             -a <adapter>       : (for use with -c only) adapter type (ide, buslogic o
    r lsilogic)
             -s <size>          : capacity of the virtual disk
             -t <disk-type>     : disk type id

          Disk types:
             0                  : single growable virtual disk
             1                  : growable virtual disk split in 2Gb files
             2                  : preallocated virtual disk
             3                  : preallocated virtual disk split in 2Gb files

          The capacity can be specified in sectors, Kb, Mb or Gb.
          The acceptable ranges:
                                ide adapter : [100.0Mb, 950.0Gb]
                                scsi adapter: [100.0Mb, 950.0Gb]

             ex 1: vmware-vdiskmanager.exe -c -s 850Mb -a ide -t 0 myIdeDisk.vmdk
             ex 2: vmware-vdiskmanager.exe -d myDisk.vmdk
             ex 3: vmware-vdiskmanager.exe -r sourceDisk.vmdk -t 0 destinationDisk.vm
    dk
             ex 4: vmware-vdiskmanager.exe -x 36Gb myDisk.vmdk
             ex 5: vmware-vdiskmanager.exe -n sourceName.vmdk destinationName.vmdk
             ex 6: vmware-vdiskmanager.exe -k myDisk.vmdk
             ex 7: vmware-vdiskmanager.exe -p <mount-point>
                   (A virtual disk first needs to be mounted at <mount-point>)
    -----------------------------------------------------------------
    其中的-x參數就是用來擴容的……

    如這個:vmware-vdiskmanager.exe -x 36Gb myDisk.vmdk

        解析: vmware-vdiskmanager.exe -x 大小 虛擬硬盤文件
    -------------------------------------------------------

    我的執行過程:

    D:\Program files\VMware\VMware Workstation>vmware-vdiskmanager.exe -x 12GB "F:\Windows Server 2003 Enterprise Edition\Windows Server 2003 Enterprise Edition.vmdk"
    ==================================================================
    總結一下:
    1。文件名應該用雙引號括起來。
    2。vmdk文件名要連同路徑。
    3。GB,MB,別忘了B。

    posted @ 2009-08-20 11:22 forgood 閱讀(528) | 評論 (0)編輯 收藏

    財務公司金融債券的概念

     

      什么是金融債券?金融債券有哪些種類?
      金融債券是由銀行和非銀行金融機構發行的債券。在英、美等歐美國家,金融機構發行的債券歸類于公司債券。在我國及日本等國家,金融機構發行的債券稱為金融債券。 金融債券能夠較有效地解決銀行等金融機構的資金來源不足和期限不匹配的矛盾。

             一般來說,銀行等金融機構的資金有三個來源,即吸收存款、向其他機構借款和發行債券。
            存款資金的特點之一,是在經濟發生動蕩的時候,易發生儲戶爭相提款的現象,從而造成資金來源不穩定;
            向其他商業銀行或中央銀行借款所得的資金主要是短期資金,而金融機構往往需要進行一些期限較長的投融資,這樣就出現了資金來源和資金運用在期限上的矛盾,發行金融債券比較有效地解決了這個矛盾。債券在到期之前一般不能提前兌換,只能在市場上轉讓,從而保證了所籌集資金的穩定性。同時,金融機構發行債券時可以靈活規定期限,比如為了一些長期項目投資,可以發行期限較長的債券。因此,發行金融債券可以使金融機構籌措到穩定且期限靈活的資金,從而有利于優化資產結構,擴大長期投資業務。由于銀行等金融機構在一國經濟中占有較特殊的地位,政府對它們的運營又有嚴格的監管,因此,金融債券的資信通常高于其他非金融機構債券,違約風險相對較小,具有較高的安全性。所以,金融債券的利率通常低于。般的企業債券,但高于風險更小的國債和銀行儲蓄存款利率。

              按不同標準,金融債券可以劃分為很多種類。最常見的分類有以下兩種:
           (1) 根據利息的支付方式 金融債券可分為附息金融債券和貼現全融債券。如果金融債券上附有多期息票,發行人定期支付利息,則稱為附息金融債券;如果金融債券是以低于面值的價格貼現發行,到期按面值還本付息,利息為發行價與面佰的差額,則稱為貼現債券。比如票面金額為1000元,期限為1年的貼現金融債券,發行價格為900元,1年到期時支付給投資者1000元,那么利息收入就是100元,而實際年利率就是11.11%(即<1 000-900>/900* 100%〕。按照國外通常的做法,貼現金融債券的利息收入要征稅,并且不能在證券交易所上市交易。
            (2) 根據發行條件 金融債券可分為普通金融債券和累進利息金融債券。普通金融債券按面值發行,到期一次還本付息,期限一般是1年、2年和3年。普通金融債券類似于銀行的定期存款,只是利率高些。累進利息金融債券的利率不固定,在不同的時間段有不同的利率,并且一年比一年高,也就是說,債券的利率隨著債券期限的增加累進,比如面值1000無、期限為5年的金融債券,第回年利率為9%,第二年利率為10%,第三年為11%,第四年為12%,第五年為13%。投資者可在第一年至第五年之間隨時去銀行兌付,并獲得規定的利息。 
            此外,金融債券也可以像企業債券一樣,根據期限的長短劃分為短期債券、中期債券和長期債券;根據是否記名劃分為記名債券和不記名債券;根據擔保情況劃分為信用債券和擔保債券;根據可否提前贖回劃分為可提前贖回債券和不可提前贖回債券;根據債券票面利率是否變動劃分為固定利率債券、浮動利率債券和累進利率債券;根據發行人是否給予投資者選擇權劃分為附有選擇權的債券和不附有選擇權的偵券等。

    posted @ 2009-08-09 22:48 forgood 閱讀(407) | 評論 (0)編輯 收藏

    正則表達式學習資料

    學習資源:

    http://www.cnblogs.com/jimmyzhang/archive/2007/10/24/936151.html (花上1-2個小時仔細學習,然后反復實踐,能夠很快上手)

    正則表達式工具:

    我首推RegexBuddy了。下面這個地址里有RegexBuddy3.2.1完整版的下載地址(如果你仔細瀏覽這個網站,會發現此人是一個正則表達式狂熱分子):

    http://iregex.org/blog/regexbuddy321.html

    posted @ 2009-07-19 18:03 forgood 閱讀(226) | 評論 (0)編輯 收藏

    js判斷頁面關閉的方法

    1、<script language="javascript">

    window.onbeforeunload = function()

    {

     if(((event.clientX > document.body.clientWidth - 43) && (event.clientY < 23)) || event.altKey) {

      window.event.returnValue = '關閉。';   

     }

    }

    </script>

    2、<script language="javascript">

    window.onbeforeunload = function()

    {

    var n = window.event.screenX - window.screenLeft;

    var b = n > document.documentElement.scrollWidth-20;

    if(b && window.event.clientY < 0 || window.event.altKey)

    {

    alert("是關閉而非刷新");

    window.open(this.location); 

    //return false;

    //window.event.returnValue = ""; }

    }

    </script>


    本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/ajaxchen_615/archive/2009/07/06/4325917.aspx

    posted @ 2009-07-06 22:17 forgood 閱讀(1312) | 評論 (0)編輯 收藏

    ie7和ie8瀏覽器中網頁不兼容的問題處理

    如果你的頁面對IE7兼容沒有問題,又不想大量修改現有代碼,同時又能在IE8中正常使用,微軟聲稱,開發商僅需要在目前兼容IE7的網站上添加一行代碼即可解決問題,此代碼如下:
    CODE:
    <meta http-equiv="x-ua-compatible" content="ie=7" />

    posted @ 2009-07-06 22:12 forgood 閱讀(315) | 評論 (0)編輯 收藏

    記錄今天

        從今天開始學習.net開發,java開發工作暫放一放,不過在學習.net的過程中,會結合java對比,在學習新知識的同時也鞏固和復習一下java的知識,在學習中提升,在學習中成長,加油!

    posted @ 2009-07-06 09:13 forgood 閱讀(147) | 評論 (0)編輯 收藏

    js對象學習筆記(二)

    1.對象和屬性

        對象是一種復核數據類型,它們將多個數據值幾種在一個單元中,而且允許使用名字來存取這些值,即對象是一個無序的屬性集合,這個屬性都有自己的名字和值,存儲在對象中的以命名的值可以是數字和字符串這樣的原始值,也可以是對象。

    2.對象的創建

        對象是由運算符new來創建的,在這個運算符之后必須有用于初始化對象的構造函數名。

        創建一個空對象(即沒有屬性的對象)

        var o = new Object();

        js還支持內部構造函數,它們以另一種簡潔的方式初始化新創建的對象

        var now = new Date();

        var new_year = new Date(2009,09,19);

    3.屬性的設置和查詢

    4.屬性的枚舉

        for/in循環列出的屬性并沒有特定順序,而且它只能枚舉出所有用戶定義的屬性,但是卻不能枚舉出那些預定義的屬性或方法,并且它可以

    枚舉出被設為undefined的屬性,但是它不能列出被delete刪除的屬性。

    5.未定義的屬性

        如果要讀取一個不存在屬性的值,那么得到的結果是一個特殊的js值,undefined

        可以使用delete來刪除一個對象的屬性,注意:刪除一個屬性并不僅僅是把該屬性設置為undefined,而是真正從對象中移除了該屬性。

    6.構造函數

        它由new運算符調用,傳遞給它的是一個新創建的空對象引用,將該引用作為關鍵字this的值,而且它還要對新創建的對象進行適當的初始化。

        注意:構造函數如何使用它的參數來初始化this關鍵字所引用的對象的屬性,記住,構造函數只是初始化了特定的對象,但并不返回這個對象。

        構造函數通常沒有返回值,他們只是初始化由this值傳遞進來的對象,并且什么也不返回..但是,構造函數可以返回一個對象值,如果這樣做,被返回的對象就成了new表達式的值了,在這種情況下,

    this值所引用的對象就被丟棄了。

    7.方法

        方法有一個非常重要的屬性,即在方法主體內部,關鍵字this的值變成了調用該方法的對象。

        方法和函數的區別,其實他們沒有什么技術上的差別,真正的區別存在于設計和目的上,方法是用來對this對象進行操作的,而函數通常是獨立的,并不需要使用this對象。

    8.原型對象和繼承

        js對象都“繼承”原型對象的屬性,每個對象都有原型對象,原型對象的所有屬性是以它為原型的對象的屬性,也就是說,每個對象都繼承原型對象的所有屬性,

        一個對象的原型是有創建并初始化該對象的構造函數定義的,js中的所有函數都有prototype屬性,它引用一個對象,雖然原型對象初始化時是空的,但是你在其中定義的任何屬性都會被構造函數創建

    的所有對象繼承。

        構造函數定義了對象的類,并初始化了類中狀態變量的屬性,因為原型對象和構造函數關聯在一起,所以類的每個成員都從原型對象繼承了相同的屬性,這說明原型對象是存放方法和其他常量屬性的理

    想場所。

        繼承是在查詢一個屬性值時自動發生的,屬性并非從原型對象賦值到新的對象的,他們只不過看起來像是那些對象的屬性,有兩點重要的含義,一是:使用原型對象可以大量減少每個對象對內存的需求

    量,因為對象可以繼承許多屬性;而且即使屬性在對象被創建之后才添加屬性到它的原型對象中,對象也能夠繼承這些屬性。

        屬性的繼承只發生在讀屬性值時,而在寫屬性值時不會發生。

        因為原型對象的屬性被一個類的所有對象共享,所以通常只用他們來定義類中所有對象的相同的屬性,這使得原型對象適合于方法定義,另外原型對象還適合于具有常量的屬性的定義,

    a.原型和內部類

     不只是用戶定義的類有原型對象,像內部類同樣具有原型對象,也可以給他們賦值,

    e.g    String.prototype.endsWith = function(o){

                return (e == this,charAt(this.length-1));

            }

    9.面向對象的js

        在面向對象的程序設計中,共有的概念是強類型和支持以類為基礎的繼承機制,根據這個評判標準,就可以證明js不是面向對象語言。

        js對象可以具有大量的屬性,而且還可以動態的將這些屬性添加到對象中,這是對面對象c++和java做不到的,

        雖然js沒有類的概念,但是它用構造函數和原型對象模擬了類。

        js和以類為基礎的面向對象語言中,同一個類可以具有多個對象,對象是它所屬的那個類的實力,所以任何類都可以有多個實例,js中的命名延勇了java中的命名約定,即命名類時以大寫字母開頭,命名對象時以小寫字母開頭,類幫助我們區分代碼中的類和對象。

    實例屬性

        每個對象都有它自己單據的實力屬性的副本,為了模擬面向對象的程序設計語言,js中的實例屬性是那些在對象中用構造函數創建的或初始化的屬性。

    實例方法

        實例方法和實例數據非常的相似,實例方法是由特定對象或實例調用的,實例方法使用了關鍵字this來引用他們要操作的對象或實例,但是和實例屬性不同額一點是每個實例方法都是由類的所有實例共享的,在js中,給類定義一個實例方法,是通過把構造函數的原型對象中的一個屬性設置為函數值類實現的,這樣,由那個構造函數創建的所有對象都會共享一個以繼承的對函數的引用,而且使用上面素數的方法調用語法就能夠調用這個函數。

    類屬性

       類屬性是一個與類相關聯的變量,而不是和類的每個實例相關聯的變量,每個類屬性只有一個副本,它是通過類存取的,可以簡單的定義了構造函數自身的一個屬性來定義類屬性

    類方法

        類方法是一個與類關聯在一起的方法,而不是和類的實例關聯在一起的方法,要調用類方法,就必須使用類本身,而不是使用類的特定實例。由于類方法不能通過一個特定對象調用,所以使用關鍵字this對它來說沒有意義,和類屬性一樣,類方法是全局性的,

    超類和子類

        面向對象語言中有類層次的概念,每個類都有一個超類,他們從超類中繼承屬性和方法,類還可以被擴展,或者說子類化,這樣其他子類就能繼承它的行為,js中繼承是以原型為基礎的,而不是以類基礎的繼承機制,但是我們仍舊能夠總結出累世的類層次圖,在js中,類Object是最通用的類,其他所有類都是專用化了的版本,或者說的是Object的子類,另一種解釋方法是Object是所有內部類的超類,所有類都繼承了Object的基本方法。

       舉例說明:

            類Complex的對象就繼承了Complex.prototype對象的屬性,而后者又繼承了Object.prototype的屬性,由此可以推出,對象Complex繼承了兩個對象的屬性,在Complex對象中查詢某個屬性時,首先查詢的是這個對象本身,如果在這個對喜愛那個中沒有發現要查詢的屬性,就查詢Complex.prototype對象,最后,如果在那個對象中還沒有最后按到要查詢的屬性,就查詢Object.prototype對象,注意類層次關系中的屬性隱藏。參考P153

    10.作為關聯數組的對象

        運算符“.”類存取一個對象屬性,而數組更常用的存取書香運算賦是[],下面的兩行代碼是等價的:

        obj.property   ====== obj["property"],他們的語法區別是,前者的屬性名是標識符,后者的屬性名卻是一個字符串,

        在c、c++、java和其他類似的強類型語言中,一個對象的屬性數是固定,而且必須預定義這些屬性的名字,由于js是一種弱類型語言,它并沒有采用這一規則,所以在用js編寫的程序,可以為對象創建任意數目的屬性,但是當你采用“.”運算符來存取一個對象的屬性時,屬性名時是用標識符表示的,而js程序性中,標識符必須被逐字的輸入,他們不是一種數據類型,因此程序不能對他們進行操作。

        constructor屬性

            每個對象都有constructor屬性,它引用的是用來初始化該對象的構造函數。但是并不是所有的對象都具有自己唯一的constructor屬性,相反,如果這個屬性是從原型對象繼承來的。

            js會為我們定義的每一個構造函數都創建一個原型對象,并且將那個對象賦給構造函數的prototype屬性。但是之前沒有說明原型對象初始時是非空的,在原型對象創建之初,它包括一個constructor屬性, 用來引用構造函數,也就是說,如果有一個函數f,那么屬性f.prototype.constructor就總是等于f的。

            由于構造函數定義了一個對象的類,所以屬性construtor在確定給定對象的類型時是一個功能強大的工具。

            并不能保證constructor屬性總是存在的,例如,一個類的創建者可以用一個全新的對象來替換構造函數的原型對象,而新對象可能不具有有效的constructor屬性。

            

        toString()方法

        toLocaleString()方法

        valueOf()方法

            js需要將一個對象轉化成字符創之外的原型類型時,就調用它,這個函數返回的是能代表關鍵字this所引用的對象的值的數據。

        hasOwnProperty()

            如果兌現局部定義了一個非繼承的屬性,屬性名是由一個字符串實際參數指定的,那么該方法就返回true,否則,它將返回false。

        propertyIsEnumerable()

            如果對象定義了一個屬性,屬性名是由一個字符串實際參數指定的,而且該屬性可以用for/in循環枚舉出來,那么該方法返回true,否則返回false。

        注意:該方法只考慮對象直接定義的屬性,而不考慮繼承的屬性,因為返回false可能是因為那個屬性是不可枚舉的,也可能是因為它雖然是可以枚舉的,但卻是個繼承的屬性。

        怎么判斷一個屬性是可枚舉的?

        isPrototypeOf()

         如果調用對象是實際參數指定的對象的原型對象,該方法返回true,否則返回false,該方法的用途和對象的constructoe屬性相似。

            

     

     

                               

        

       

    posted @ 2009-03-26 14:32 forgood 閱讀(986) | 評論 (1)編輯 收藏

    js中的函數學習(一)

    1.函數

        注意:定義函數時可以使用個數可變的參數,而且函數既可以有return語句,也可以沒有return語句;如果函數不包含return語句,它就只執行函數體中的每條語句,然后返回給調用者undefined。

        使用運算符typeof來檢測參數的數據類型,使用if(!param)return;來判斷是否存在該參數,因為js是一種無類型語言,所以你不能給函數的參數制定一個數據類型,而且js也不會檢測傳遞的數據是不是那個函數所需要的類型,如果參數很重要時,就使用前面介紹的運算符進行檢測。

        不可變參數js的處理:如果傳遞的參數比函數需要的個數多,那么多余的幾個參數被忽略掉,如果傳遞的參數比函數需要的個數少,那么多余的幾個參數就會被賦予undefined,在大多數情況下,這回使得函數產生錯誤。

    2.嵌套函數

        a,函數定義中可以嵌套其他函數的定義,但是只能在在頂層全局代碼和頂層函數代碼中,不能出現在循環或條件語句中,并且這些限制只應用于由function語句聲明的函數,函數直接量可以出現在任何js表達式中。

    3.Function()構造函數

        可以使用Function()構造函數和new運算符動態地定義函數, var f = new Function("x","y","return x*y;");它等價于:function f(x,y){return x*y;}

        Function構造函數可以接受任意多個字符串參數,它的最后一個參數是函數的主體,其中可以包含任何js語句,語句之間用分號分隔。由于傳遞給構造函數Function()的參數中沒有一個用于說明它要創建的函數名,用Function()構造函數創建的未命名函數有時被稱作為“匿名函數”。

        Function()函數存在的意義:因為Function()構造函數允許我們動態地建立和編譯一個函數,它不會將我們限制在function語句預編譯的函數體中;另一個原因是它能將函數定義為js表達式的一部分,而不是將其定義為一個語句;缺點是:這樣做每次調用一個函數時,Function()構造函數都要對它進行編譯,

    4.函數直接量

        函數直接量是一個表達式,它可以定義匿名函數。

        function f(x){return x*x;}                  //function語句

        var f = new Function("x","return x*x;");    //Function()構造函數

        var f = function(X){return x*x;};           //函數直接量

        雖然函數直接量創建的是未命名函數,但是它的語法也規定它可以指定函數名,這在編寫調用自身的遞歸函數時特別的有用,e.g

    var f= function fact(x){if(x<=1)return 1; else return x*fact(x-1);}

    總結:function()函數可以任意的使用,具有通用性,Function()函數和函數直接量具有很多的相似性,他們都是未命名函數(函數直接量可以有函數名,尤其是在子調用函數中),函數直接量有個重要的有點,函數直接量只被解析和編譯一次,而作為字符串傳遞給Function()構造函數的js代碼則在每次調用構造函數時只需要被解析和編譯一次。

    函數最重要的特性就是他們能夠被定義和調用,但是在js中函數并不只是一種語法,還可以是數據,可以把函數賦給變量、存儲在對象的屬性中或存儲在數組的元素中,傳遞給函數。其實函數名并沒有什么實際意義,它只是保存函數的變量的名字,可以將這個函數賦給其他的變量,它仍然以相同的方式起作用,

    e.g    function square(x){x*x;}

    var a = square(4);

    var b = square;//這種情況下b引用的函數和square的作用相同

    var c = b(5);

    除了賦給全局變量之外,還可以將函數賦給對象的屬性,這是稱函數為方法;也可以賦給數組元素。

    e.g

        var a =  new Object;     var a = new Object();

        a.square = new Function("x","return x*x";);

        y = o.square(16);

    e.g   

        var a = new Array(3);

        a[0] = function(x){return x*x;};

        a[1] = 20;

        a[2] = a[0](a[1]);

        除這些之外,如何將函數作為參數傳遞給其他函數,

    e.g

    function  add(x,y){return x+y;}

    function subtract(x,y){return x-y;}

    function multiply(x,y){return x*y;}

    function dibide(x,y){return x/y;}

    function operate(operator,operand1,operand2){

        return operator(operand1,operand2);

    }

    var i = operate(add,operate(add,2,3),operate(multiply,4,5));

    var operators = new Object();

    operators["add"] = function(x,y){return x+y;}

    operators["multiply"] = function(x,y){return x*y;}

    operators["divide"] = function(x,y){return x/y;}

    operators["pow"] = Math.pow;

    function operate2(op_name,operand1,operand2){

        if(operators[op_name] == null)return "unknow operator";

        else    return operators[op_name](operand1,operand2);

    }

    var j = operate2('add',"hello",operate2("add","","world"));

    var k = operate2('pow',10,2);

    5.函數的作用域,調用對象

        函數的作用域中除了全局變量、函數內部的局部變量和形式參數外,函數還定義了一個特殊屬性,

        arguments,這個屬性應用了另外一個特殊的對象-----Arguments對象,因為arguments屬性是調用對象的一個屬性,所以它的狀態和局部變量以及函數的形式參數是相同的。

        所以arguments標識符被看做是保留字,不能將它作為變量名或形式參數名。

    6.Arguments對象

        arguments它具有特殊的意義,是調用對象的一個特殊屬性,用來引用Arguments對象,Arguments對象就像數組,可以按照數字獲取傳遞給函數的參數值,但是它并非真正的Array對象。

        arguments具有length屬性,

        可以使用arguments來檢測調用函數使用了正確數目的實際參數,

    注意:arguments并非真正的數組,它是一個Arguments對象,Arguments對象有一個非同尋常的特征,當函數具有命名了的參數時,Arguments對象的數組元素是存放函數參數的局部變量的同義詞。

    e.g 

      function(x){

        alert(x);  //顯示參數的初始值

        arguments[0] = null;//改變數組預算也會改變x

        alert(x);  //現在顯示為“null”

    除了數組元素,Arguments對象還定義了callee屬性,用來引用當前正在執行的函數,這對未命名的函數調用自身非常有用。

    e.g

     function(x){

        if(x<-1)return 1;

        return x*arguments.callee(x-1);

    }

    7.函數的屬性和方法

        由于函數是對象,所以它具有數據和方法。

    函數的length屬性

        函數的屬性length和arguments屬性的length不同,arguments數組的length屬性指定了傳遞給該函數的實際參數數目,并且arguments屬性的length只在函數內部起作用,而函數自身的length屬性它是只讀的,返回的是函數需要的實際參數的數目,并且函數的屬性length函數體的內部和外部都在是有效的

    函數的prototype屬性

        每個函數都有一個prototype屬性,它引用的是預定義的原型對象,原型對象在使用new運算符把函數作為構造函數時起作用。

    函數自定義屬性

        有時候定義全局變量比較亂,可以通過自定義函數屬性來解決

    函數的apply()和call()方法

        他們的第一個參數都是要調用的函數的對象,在函數體內這一參數是關鍵字this的值,call()的剩余參數是傳遞給要調用的函數的值,apply()的剩余參數是由數組指定的參數。

    posted @ 2009-03-21 12:45 forgood 閱讀(1092) | 評論 (0)編輯 收藏

    漂亮代碼七法

    寫出漂亮代碼的七種方法

    首先我想說明我本文闡述的是純粹從美學的角度來寫出代碼,而非技術、邏輯等。以下為寫出漂亮代碼的七種方法:



    1, 盡快結束 if語句



    例如下面這個JavaScript語句,看起來就很恐怖:



    Java代碼 復制代碼
    1. 1 function findShape(flags, point, attribute, list) {   
    2.   
    3. 2    if(!findShapePoints(flags, point, attribute)) {   
    4.   
    5. 3        if(!doFindShapePoints(flags, point, attribute)) {   
    6.   
    7. 4            if(!findInShape(flags, point, attribute)) {   
    8.   
    9. 5                if(!findFromGuide(flags,point) {   
    10.   
    11. 6                    if(list.count() > 0 && flags == 1) {   
    12.   
    13. 7                          doSomething();   
    14.   
    15. 8                    }   
    16.   
    17. 9                }   
    18.   
    19. 10            }   
    20.   
    21. 11       }   
    22.   
    23. 12    }      
    24.   
    25. 13  }  


    但如果這么寫就好看得多:
    Java代碼 復制代碼
    1. 1 function findShape(flags, point, attribute, list) {   
    2.   
    3. 2    if(findShapePoints(flags, point, attribute)) {   
    4.   
    5. 3        return;   
    6.   
    7. 4    }   
    8.   
    9. 5    
    10.   
    11. 6    if(doFindShapePoints(flags, point, attribute)) {   
    12.   
    13. 7        return;   
    14.   
    15. 8    }   
    16.   
    17. 9    
    18.   
    19. 10    if(findInShape(flags, point, attribute)) {    
    20.   
    21. 11        return;   
    22.   
    23. 12    }   
    24.   
    25. 13    
    26.   
    27. 14    if(findFromGuide(flags,point) {   
    28.   
    29. 15        return;   
    30.   
    31. 16    }   
    32.   
    33. 17    
    34.   
    35. 18    if (!(list.count() > 0 && flags == 1)) {   
    36.   
    37. 19        return;   
    38.   
    39. 20    }   
    40.   
    41. 21    
    42.   
    43. 22    doSomething();   
    44.   
    45. 23    
    46.   
    47. 24 }  



    你可能會很不喜歡第二種的表述方式,但反映出了迅速返回if值的思想,也可以理解為:避免不必要的else陳述。



    2, 如果只是簡單的布爾運算(邏輯運算),不要使用if語句



    例如:
    Java代碼 復制代碼
    1. 1 function isStringEmpty(str){   
    2.   
    3. 2    if(str === "") {    
    4.   
    5. 3        return true;   
    6.   
    7. 4    }   
    8.   
    9. 5    else {   
    10.   
    11. 6        return false;   
    12.   
    13. 7    }   
    14.   
    15. 8 }  


    可以寫為:
    Java代碼 復制代碼
    1. 1 function isStringEmpty(str){   
    2.   
    3. 2    return (str === "");   
    4.   
    5. 3 }  

    3, 使用空白,這是免費的

    例如:

    1
    Java代碼 復制代碼
    1.  function getSomeAngle() {   
    2.   
    3. 2    // Some code here then   
    4.   
    5. 3    radAngle1 = Math.atan(slope(center, point1));   
    6.   
    7. 4    radAngle2 = Math.atan(slope(center, point2));   
    8.   
    9. 5    firstAngle = getStartAngle(radAngle1, point1, center);   
    10.   
    11. 6    secondAngle = getStartAngle(radAngle2, point2, center);   
    12.   
    13. 7    radAngle1 = degreesToRadians(firstAngle);   
    14.   
    15. 8    radAngle2 = degreesToRadians(secondAngle);   
    16.   
    17. 9    baseRadius = distance(point, center);   
    18.   
    19. 10    radius = baseRadius + (lines * y);   
    20.   
    21. 11    p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);   
    22.   
    23. 12    p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);   
    24.   
    25. 13    pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);   
    26.   
    27. 14    pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");   
    28.   
    29. 15    // Now some more code   
    30.   
    31. 16 }  


    很多開發者不愿意使用空白,就好像這要收費一樣。我在此并非刻意地添加空白,粗魯地打斷代碼的連貫性。在實際編寫代碼的過程中,會很容易地發現在什么地方加入空白,這不但美觀而且讓讀者易懂,如下:

    Java代碼 復制代碼
    1. 1 function getSomeAngle() {   
    2.   
    3. 2    // Some code here then   
    4.   
    5. 3    radAngle1 = Math.atan(slope(center, point1));   
    6.   
    7. 4    radAngle2 = Math.atan(slope(center, point2));   
    8.   
    9. 5    
    10.   
    11. 6    firstAngle = getStartAngle(radAngle1, point1, center);   
    12.   
    13. 7    secondAngle = getStartAngle(radAngle2, point2, center);   
    14.   
    15. 8    
    16.   
    17. 9    radAngle1 = degreesToRadians(firstAngle);   
    18.   
    19. 10    radAngle2 = degreesToRadians(secondAngle);   
    20.   
    21. 11    
    22.   
    23. 12    baseRadius = distance(point, center);   
    24.   
    25. 13    radius = baseRadius + (lines * y);   
    26.   
    27. 14    
    28.   
    29. 15    p1["x"] = roundValue(radius * Math.cos(radAngle1) + center["x"]);   
    30.   
    31. 16    p1["y"] = roundValue(radius * Math.sin(radAngle1) + center["y"]);   
    32.   
    33. 17    
    34.   
    35. 18    pt2["x"] = roundValue(radius * Math.cos(radAngle2) + center["y"]);   
    36.   
    37. 19    pt2["y"] = roundValue(radius * Math.sin(radAngle2) + center["y");   
    38.   
    39. 20    // Now some more code   
    40.   
    41. 21 }   
    42.   
    43.   
    44.   
    45. 4, 不要使用無謂的注釋   
    46.   
    47. 無謂的注釋讓人費神,這實在很討厭。不要標出很明顯的注釋。在以下的例子中,每個人都知道代碼表達的是“students id”,因而沒必要標出。   
    48.   
    49. 1 function existsStudent(id, list) {   
    50.   
    51. 2    for(i = 0; i < list.length; i++) {   
    52.   
    53. 3       student = list[i];   
    54.   
    55. 4    
    56.   
    57. 5       // Get the student's id   
    58.   
    59. 6       thisId = student.getId();   
    60.   
    61. 7    
    62.   
    63. 8       if(thisId === id) {   
    64.   
    65. 9           return true;   
    66.   
    67. 10       }   
    68.   
    69. 11    }   
    70.   
    71. 12    return false;      
    72.   
    73. 13 }  



    5, 不要在源文件中留下已經刪除的代碼,哪怕你標注了

    如果你使用了版本控制,那么你就可以輕松地找回前一個版本的代碼。如果別人大費周折地讀了你的代碼,卻發現是要刪除的代碼,這實在太恨人了。


    Java代碼 復制代碼
    1. //function thisReallyHandyFunction() {   
    2.   
    3. //      someMagic();   
    4.   
    5. //      someMoreMagic();   
    6.   
    7. //      magicNumber = evenMoreMagic();   
    8.   
    9. //      return magicNumber;   
    10.   
    11. //}  


    6,不要有太長的代碼



    看太長的代碼實在太費勁,尤其是代碼本身的功能又很小。如下:


    Java代碼 復制代碼
    1. 1 public static EnumMap<Category, IntPair> getGroupCategoryDistribution(EnumMap<Category, Integer> sizes, int groups) {   
    2.   
    3. 2        EnumMap<Category, IntPair> categoryGroupCounts = new EnumMap<Category,IntPair>(Category.class);   
    4.   
    5. 3    
    6.   
    7. 4        for(Category cat : Category.values()) {   
    8.   
    9. 5            categoryGroupCounts.put(cat, getCategoryDistribution(sizes.get(cat), groups));   
    10.   
    11. 6        }  


    #



    我并不是說非要堅持70個字符以內,但是一個比較理想的長度是控制在120個字符內。如果你把代碼發布在互聯網上,用戶讀起來就很困難。

    7,不要在一個功能(或者函數內)有太多代碼行

    我的一個老同事曾經說Visual C++很臭,因為它不允許你在一個函數內擁有超過10,000行代碼。我記不清代碼行數的上限,不知道他說的是否正確,但我很不贊成他的觀點。如果一個函數超過了50行,看起來有多費勁你知道么,還有沒完沒了的if循環,而且你還的滾動鼠標前后對照這段代碼。對我而言,超過35行的代碼理解起來就很困難了。我的建議是超過這個數字就把一個函數代碼分割成兩個。

    posted @ 2009-01-18 14:33 forgood 閱讀(224) | 評論 (0)編輯 收藏

    反射機制補充

    本篇文章為在工作中使用JAVA反射的經驗總結,也可以說是一些小技巧,以后學會新的小技巧,會不斷更新。

            在開始之前,我先定義一個測試類Student,代碼如下:

    1. package chb.test.reflect;   
    2.   
    3. public class Student {   
    4.     private int age;   
    5.     private String name;   
    6.     public int getAge() {   
    7.         return age;   
    8.      }   
    9.     public void setAge(int age) {   
    10.         this.age = age;   
    11.      }   
    12.     public String getName() {   
    13.         return name;   
    14.      }   
    15.     public void setName(String name) {   
    16.         this.name = name;   
    17.      }   
    18.        
    19.     public static void hi(int age,String name){   
    20.          System.out.println("大家好,我叫"+name+",今年"+age+"歲");   
    21.      }   
    22. }<PRE></PRE>  

    一、JAVA反射的常規使用步驟

        反射調用一般分為3個步驟:

    • 得到要調用類的class
    • 得到要調用的類中的方法(Method)
    • 方法調用(invoke)

         代碼示例:

    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Method m = cls.getDeclaredMethod("hi",new Class[]{int.class,String.class});   
    3. m.invoke(cls.newInstance(),20,"chb");<PRE></PRE>  

    二、方法調用中的參數類型

            在方法調用中,參數類型必須正確,這里需要注意的是不能使用包裝類替換基本類型,比如不能使用Integer.class代替int.class。

           如我要調用Student的setAge方法,下面的調用是正確的:

    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Method setMethod = cls.getDeclaredMethod("setAge",int.class);   
    3. setMethod.invoke(cls.newInstance(), 15);<PRE></PRE>  

     

           而如果我們用Integer.class替代int.class就會出錯,如:

    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);   
    3. setMethod.invoke(cls.newInstance(), 15);<PRE></PRE>  

     

           jvm會報出如下異常:

    1. java.lang.NoSuchMethodException: chb.test.reflect.Student.setAge(java.lang.Integer)   
    2.      at java.lang.Class.getDeclaredMethod(Unknown Source)   
    3.      at chb.test.reflect.TestClass.testReflect(TestClass.java:23)<PRE></PRE>  

     

    三、static方法的反射調用

     

           static方法調用時,不必得到對象示例,如下:

    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Method staticMethod = cls.getDeclaredMethod("hi",int.class,String.class);   
    3. staticMethod.invoke(cls,20,"chb");//這里不需要newInstance   
    4. //staticMethod.invoke(cls.newInstance(),20,"chb");<PRE></PRE>  

    四、private的成員變量賦值

        如果直接通過反射給類的private成員變量賦值,是不允許的,這時我們可以通過setAccessible方法解決。代碼示例:

    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Object student = cls.newInstance();//得到一個實例   
    3. Field field = cls.getDeclaredField("age");   
    4. field.set(student, 10);   
    5. System.out.println(field.get(student));<PRE></PRE>  

     

         運行如上代碼,系統會報出如下異常:

    1. java.lang.IllegalAccessException: Class chb.test.reflect.TestClass can not access a member of class chb.test.reflect.Student with modifiers "private"   
    2.      at sun.reflect.Reflection.ensureMemberAccess(Unknown Source)   
    3.      at java.lang.reflect.Field.doSecurityCheck(Unknown Source)   
    4.      at java.lang.reflect.Field.getFieldAccessor(Unknown Source)   
    5.      at java.lang.reflect.Field.set(Unknown Source)   
    6.      at chb.test.reflect.TestClass.testReflect(TestClass.java:20)<PRE></PRE>  

        解決方法:

    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Object student = cls.newInstance();   
    3. Field field = cls.getDeclaredField("age");   
    4. field.setAccessible(true);//設置允許訪問   
    5. field.set(student, 10);   
    6. System.out.println(field.get(student));<PRE></PRE>  

        其實,在某些場合下(類中有get,set方法),可以先反射調用set方法,再反射調用get方法達到如上效果,代碼示例:

    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Object student = cls.newInstance();   
    3.   
    4. Method setMethod = cls.getDeclaredMethod("setAge",Integer.class);   
    5. setMethod.invoke(student, 15);//調用set方法   
    6.                
    7. Method getMethod = cls.getDeclaredMethod("getAge");   
    8. System.out.println(getMethod.invoke(student));//再調用get方法<PRE></PRE>

    posted @ 2009-01-11 17:28 forgood 閱讀(1207) | 評論 (1)編輯 收藏

    java中的反射機制

    Reflection 是 Java 程序開發語言的特征之一,它允許運行中的 Java 程序對自身進行檢查,或者說“自審”,并能直接操作程序的內部屬性。例如,使用它能獲得 Java 類中各成員的名稱并顯示出來。JavaBean 是 reflection 的實際應用之一,它能讓一些工具可視化的操作軟件組件。這些工具通過 reflection 動態的載入并取得 Java 組件(類) 的屬性。
        1. 一個簡單的例子
        考慮下面這個簡單的例子,讓我們看看 reflection 是如何工作的。
        import java.lang.reflect.*;
        public class DumpMethods {
            public static void main(String args[]) {
                try {
                    Class c = Class.forName(args[0]);
                    Method m[] = c.getDeclaredMethods();
                    for (int i = 0; i < m.length; i++)
                        System.out.println(m[i].toString());
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
        按如下語句執行:
        java DumpMethods java.util.Stack
        它的結果輸出為:
        public java.lang.Object java.util.Stack.push(java.lang.Object)
        public synchronized java.lang.Object java.util.Stack.pop()
        public synchronized java.lang.Object java.util.Stack.peek()
        public boolean java.util.Stack.empty()
        public synchronized int java.util.Stack.search(java.lang.Object)
        這樣就列出了java.util.Stack 類的各方法名以及它們的限制符和返回類型。
        這個程序使用 Class.forName 載入指定的類,然后調用 getDeclaredMethods 來獲取這個類中定義了的方法列表。java.lang.reflect.Methods 是用來描述某個類中單個方法的一個類。還有就是getDeclaredMethod(para1,para2)來獲取這個類中的具體某一個方法,其中para1是一個String類型,具體代表的是方法名,para2是個一個Class類型的數組,其中定義個方法的具體參數類型。
        例如:
    1. Class cls = Class.forName("chb.test.reflect.Student");   
    2. Method m = cls.getDeclaredMethod("方法名",new Class[]{int.class,String.class});   
    3. m.invoke(cls.newInstance(),20,"chb");
        總結:
                //使用反射類調用某個類中的方法
                   Class c = Class.forName("com.inspur.reflect.MethodTest");
                   Method n = c.getDeclaredMethod("show", new Class[]{String.class,int.class});
                   n.invoke(c.newInstance(), "guoxzh",20);
       a.使用Class.forName("類名")來獲取類
       b.其次使用getDeclaredMethods()方法獲取該類所有的方法,也可以使用getDeclaredMethod("方法名",new Class[]{int.class,String.class})方法類獲取具體的某一個方法
       c.接著可以使用invoke(c.newInstance,param....)來調用具體的方法。


        2.詳細介紹開始使用 Reflection
        用于 reflection 的類,如 Method,可以在 java.lang.relfect 包中找到。使用這些類的時候必須要遵循三個步驟:第一步是獲得你想操作的類的 java.lang.Class 對象。在運行中的 Java 程序中,用 java.lang.Class 類來描述類和接口等。
        下面就是獲得一個 Class 對象的方法之一:
        Class c = Class.forName("java.lang.String");
        這條語句得到一個 String 類的類對象。還有另一種方法,如下面的語句:
        Class c = int.class;
        或者
        Class c = Integer.TYPE;
        它們可獲得基本類型的類信息。其中后一種方法中訪問的是基本類型的封裝類 (如 Integer) 中預先定義好的 TYPE 字段。
        第二步是調用諸如 getDeclaredMethods 的方法,以取得該類中定義的所有方法的列表。
        一旦取得這個信息,就可以進行第三步了——使用 reflection API 來操作這些信息,如下面這段代碼:
        Class c = Class.forName("java.lang.String");
        Method m[] = c.getDeclaredMethods();
        System.out.println(m[0].toString());
        它將以文本方式打印出 String 中定義的第一個方法的原型。
        在下面的例子中,這三個步驟將為使用 reflection 處理特殊應用程序提供例證。
        模擬 instanceof 操作符
        得到類信息之后,通常下一個步驟就是解決關于 Class 對象的一些基本的問題。例如,Class.isInstance 方法可以用于模擬 instanceof 操作符:
        class A {
        }
        public class instance1 {
            public static void main(String args[]) {
                try {
                    Class cls = Class.forName("A");
                    boolean b1 = cls.isInstance(new Integer(37));   //判斷Integer(37)該對象是否是A類的對象
                    System.out.println(b1);
                    boolean b2 = cls.isInstance(new A());
                    System.out.println(b2);
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
        在這個例子中創建了一個 A 類的 Class 對象,然后檢查一些對象是否是 A 的實例。Integer(37) 不是,但 new A() 是。


        3.找出類的方法
        找出一個類中定義了些什么方法,這是一個非常有價值也非常基礎的 reflection 用法。下面的代碼就實現了這一用法:

    package com.inspur.reflect;

    import java.lang.reflect.Method;


    public class Methodtest1 {
     
     
     private int abc(Object p,int x) throws NullPointerException{
      if(p==null)throw new NullPointerException();
      return x;
     }

     public static void main(String[] args) {
      
      try{
       Class cls = Class.forName("com.inspur.reflect.Methodtest1");
       Method methodlist[]= cls.getDeclaredMethods();
       for(int i = 0;i<methodlist.length;i++){
        Method m = methodlist[i];
        System.out.println("name=="+m.getName());//得到方法的名稱
        System.out.println("decl class=="+m.getDeclaringClass());//得到定義的類名
        Class prev[] = m.getParameterTypes();   //取m方法中的所有參數
        //遍歷所有的參數
        for(int j = 0; j<prev.length;j++){
         System.out.println("param["+j+"]=="+prev[j]);
        }
        Class exec[] = m.getExceptionTypes(); //得到所有的異常
        //遍歷所有的異常
        for(int k=0;k<exec.length;k++){
         System.out.println("execption["+k+"]=="+exec[k]);
        }
       
        Class ret = m.getReturnType(); //得到每個方法的返回值
        System.out.println("return leixing=="+ret.toString()); 
       }
      }catch(Throwable e){
       System.err.println(e.getMessage());
      }
     }

    }

        這個程序首先取得 method1 類的描述,然后調用 getDeclaredMethods 來獲取一系列的 Method 對象,它們分別描述了定義在類中的每一個方法,包括 public 方法、protected 方法、package 方法和 private 方法等。如果你在程序中使用 getMethods 來代替 getDeclaredMethods,你還能獲得繼承來的各個方法的信息。同時你也可以使用Modifier.toString(m.getModifiers())來獲取方法的限制屬性。
        取得了 Method 對象列表之后,要顯示這些方法的參數類型、異常類型和返回值類型等就不難了。這些類型是基本類型還是類類型,都可以由描述類的對象按順序給出。
        輸出的結果如下:
       name==main
    decl class==class com.inspur.reflect.Methodtest1
    param[0]==class [Ljava.lang.String;
    return leixing==void
    name==abc
    decl class==class com.inspur.reflect.Methodtest1
    param[0]==class java.lang.Object
    param[1]==int
    execption[0]==class java.lang.NullPointerException
    return leixing==int    4.獲取構造器信息
        獲取類構造器的用法與上述獲取方法的用法類似,如:
        import java.lang.reflect.*;
        public class constructor1 {
            public constructor1() {
            }
            protected constructor1(int i, double d) {
            }
            public static void main(String args[]) {
                try {
                    Class cls = Class.forName("constructor1");
                    Constructor ctorlist[] = cls.getDeclaredConstructors();
                    for (int i = 0; i < ctorlist.length; i++) {
                        Constructor ct = ctorlist[i];
                        System.out.println("name = " + ct.getName());
                        System.out.println("decl class = " + ct.getDeclaringClass());
                        Class pvec[] = ct.getParameterTypes();
                        for (int j = 0; j < pvec.length; j++)
                            System.out.println("param #" + j + " " + pvec[j]);
                        Class evec[] = ct.getExceptionTypes();
                        for (int j = 0; j < evec.length; j++)
                            System.out.println("exc #" + j + " " + evec[j]);
                        System.out.println("-----");
                    }
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
        這個例子中沒能獲得返回類型的相關信息,那是因為構造器沒有返回類型。
    這個程序運行的結果是:
        name = constructor1
        decl class = class constructor1
        -----
        name = constructor1
        decl class = class constructor1
        param #0 int
        param #1 double
        -----
        5.獲取類的字段(域)
        找出一個類中定義了哪些數據字段也是可能的,下面的代碼就在干這個事情:
        import java.lang.reflect.*;
        public class field1 {
            private double d;
            public static final int i = 37;
            String s = "testing";
            public static void main(String args[]) {
                try {
                    Class cls = Class.forName("field1");
                    Field fieldlist[] = cls.getDeclaredFields();
                    for (int i = 0; i < fieldlist.length; i++) {
                        Field fld = fieldlist[i];
                        System.out.println("name = " + fld.getName());
                        System.out.println("decl class = " + fld.getDeclaringClass());
                        System.out.println("type = " + fld.getType());
                        int mod = fld.getModifiers();
                        System.out.println("modifiers = " + Modifier.toString(mod));
                        System.out.println("-----");
                    }
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
        這個例子和前面那個例子非常相似。例中使用了一個新東西 Modifier,它也是一個 reflection 類,用來描述字段成員的修飾語,如“private int”。這些修飾語自身由整數描述,而且使用 Modifier.toString 來返回以“官方”順序排列的字符串描述 (如“static”在“final”之前)。這個程序的輸出是:
        name = d
        decl class = class field1
        type = double
        modifiers = private
        -----
        name = i
        decl class = class field1
        type = int
        modifiers = public static final
        -----
        name = s
        decl class = class field1
        type = class java.lang.String
        modifiers =
        -----
        和獲取方法的情況一下,獲取字段的時候也可以只取得在當前類中申明了的字段信息 (getDeclaredFields),或者也可以取得父類中定義的字段 (getFields) 。
        6.根據方法的名稱來執行方法
        文本到這里,所舉的例子無一例外都與如何獲取類的信息有關。我們也可以用 reflection 來做一些其它的事情,比如執行一個指定了名稱的方法。下面的示例演示了這一操作:
        import java.lang.reflect.*;
        public class method2 {
            public int add(int a, int b) {
                return a + b;
            }
            public static void main(String args[]) {
                try {
                    Class cls = Class.forName("method2");
                    Class partypes[] = new Class[2];
                    partypes[0] = Integer.TYPE;
                    partypes[1] = Integer.TYPE;
                    Method meth = cls.getMethod("add", partypes);
                    method2 methobj = new method2();
                    Object arglist[] = new Object[2];
                    arglist[0] = new Integer(37);
                    arglist[1] = new Integer(47);
                    Object retobj = meth.invoke(methobj, arglist);
                    Integer retval = (Integer) retobj;
                    System.out.println(retval.intValue());
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
    假如一個程序在執行的某處的時候才知道需要執行某個方法,這個方法的名稱是在程序的運行過程中指定的 (例如,JavaBean 開發環境中就會做這樣的事),那么上面的程序演示了如何做到。
        上例中,getMethod 用于查找一個具有兩個整型參數且名為 add 的方法。找到該方法并創建了相應的 Method 對象之后,在正確的對象實例中執行它。執行該方法的時候,需要提供一個參數列表,這在上例中是分別包裝了整數 37 和 47 的兩個 Integer 對象。執行方法的返回的同樣是一個 Integer 對象,它封裝了返回值 84。
        7.創建新的對象
        對于構造器,則不能像執行方法那樣進行,因為執行一個構造器就意味著創建了一個新的對象 (準確的說,創建一個對象的過程包括分配內存和構造對象)。所以,與上例最相似的例子如下:
        import java.lang.reflect.*;
        public class constructor2 {
            public constructor2() {
            }
            public constructor2(int a, int b) {
                System.out.println("a = " + a + " b = " + b);
            }
            public static void main(String args[]) {
                try {
                    Class cls = Class.forName("constructor2");
                    Class partypes[] = new Class[2];
                    partypes[0] = Integer.TYPE;
                    partypes[1] = Integer.TYPE;
                    Constructor ct = cls.getConstructor(partypes);
                    Object arglist[] = new Object[2];
                    arglist[0] = new Integer(37);
                    arglist[1] = new Integer(47);
                    Object retobj = ct.newInstance(arglist);
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
        根據指定的參數類型找到相應的構造函數并執行它,以創建一個新的對象實例。使用這種方法可以在程序運行時動態地創建對象,而不是在編譯的時候創建對象,這一點非常有價值。
        (這里如果使用無參構造器創建對象的話,這可以直接使用Class.forName("...").newInstance();來創建對象)
        8.改變字段(域)的值
        reflection 的還有一個用處就是改變對象數據字段的值。reflection 可以從正在運行的程序中根據名稱找到對象的字段并改變它,下面的例子可以說明這一點:
        import java.lang.reflect.*;
        public class field2 {
            public double d;
            public static void main(String args[]) {
                try {
                    Class cls = Class.forName("field2");
                    Field fld = cls.getField("d");
                    field2 f2obj = new field2();
                    System.out.println("d = " + f2obj.d);
                    fld.setDouble(f2obj, 12.34);
                    System.out.println("d = " + f2obj.d);
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
        這個例子中,字段 d 的值被變為了 12.34。
        9.使用數組
        本文介紹的 reflection 的最后一種用法是創建的操作數組。數組在 Java 語言中是一種特殊的類類型,一個數組的引用可以賦給 Object 引用。觀察下面的例子看看數組是怎么工作的:
        import java.lang.reflect.*;
        public class array1 {
            public static void main(String args[]) {
                try {
                    Class cls = Class.forName("java.lang.String");
                    Object arr = Array.newInstance(cls, 10);
                    Array.set(arr, 5, "this is a test");
                    String s = (String) Array.get(arr, 5);
                    System.out.println(s);
                } catch (Throwable e) {
                    System.err.println(e);
                }
            }
        }
        例中創建了 10 個單位長度的 String 數組,為第 5 個位置的字符串賦了值,最后將這個字符串從數組中取得并打印了出來。
        下面這段代碼提供了一個更復雜的例子:
        import java.lang.reflect.*;
        public class array2 {
            public static void main(String args[]) {
                int dims[] = new int[]{5, 10, 15};
                Object arr = Array.newInstance(Integer.TYPE, dims);
                Object arrobj = Array.get(arr, 3);
                Class cls = arrobj.getClass().getComponentType();
                System.out.println(cls);
                arrobj = Array.get(arrobj, 5);
                Array.setInt(arrobj, 10, 37);
                int arrcast[][][] = (int[][][]) arr;
                System.out.println(arrcast[3][5][10]);
            }
        }
        例中創建了一個 5 x 10 x 15 的整型數組,并為處于 [3][5][10] 的元素賦了值為 37。注意,多維數組實際上就是數組的數組,例如,第一個 Array.get 之后,arrobj 是一個 10 x 15 的數組。進而取得其中的一個元素,即長度為 15 的數組,并使用 Array.setInt 為它的第 10 個元素賦值。
        注意創建數組時的類型是動態的,在編譯時并不知道其類型。

    posted @ 2009-01-11 17:27 forgood 閱讀(244) | 評論 (0)編輯 收藏

    oracle中sql優化

         摘要: 轉自其他博客《收藏》 (1)      選擇最有效率的表名順序(只在基于規則的優化器中有效): ORACLE的解析器按照從右到左的順序處理FROM子句中的表名,FROM子句中寫在最后的表(基礎表 driving table)將被最先處理,在FROM子句中包含多個表的情況下,你必須選擇記錄條數最少的表作為基礎表。如果有3個以上的表連接查詢,...  閱讀全文

    posted @ 2008-12-13 23:14 forgood 閱讀(200) | 評論 (0)編輯 收藏

    Spring和Struts整合的三種方式

    1,使用Spring 的 ActionSupport

    2,使用Spring 的 DelegatingRequestProcessor 類。

    3,全權委托。

    無論用那種方法來整合第一步就是要為struts來裝載spring的應用環境。 就是在 struts 中加入一個插件。

    struts-config.xml中

    <plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
                <set-property property="contextConfigLocation" value="/WEB-INF/applicationContext.xml"/>
                </plug-in>

    spring 的配置文件被作為參數配置進來。這樣可以省略對web.xml 文件中的配置。確保你的applicationContext.xml 在WEB-INF目錄下面

    1、使用Spring的ActionSupport .

    Spring 的ActionSupport 繼承至org.apache.struts.action.Action

    ActionSupport的子類可以或得 WebApplicationContext類型的全局變量。通過getWebApplicationContext()可以獲得這個變量。


    這是一個 servlet 的代碼:

    public class LoginAction extends org.springframework.web.struts.ActionSupport {
                public ActionForward execute(ActionMapping mapping, ActionForm form,
                HttpServletRequest request, HttpServletResponse response) {
                LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
                //獲得  WebApplicationContext  對象
                WebApplicationContext ctx = this.getWebApplicationContext();
                LoginDao dao = (LoginDao) ctx.getBean("loginDao");
                User u = new User();
                u.setName(loginForm.getName());
                u.setPwd(loginForm.getPwd());
                if(dao.checkLogin(u)){
                return mapping.findForward("success");
                }else{
                return  mapping.findForward("error");
                }
                }
                }
                applicationContext.xml 中的配置
                <beans>
                <bean id="loginDao" class="com.cao.dao.LoginDao"/>
                </beans>
                

    這中配置方式同直接在web.xml文件配置差別不大。

    注意:Action繼承自 org.springframework.web.struts.ActionSupport 使得struts和spring耦合在一起。

    但實現了表示層和業務邏輯層的解耦(LoginDao dao = (LoginDao) ctx.getBean("loginDao"))。


    2、使用Spring 的 DelegatingRequestProcessor 類

    DelegatingRequestProcessor  繼承自 org.apache.struts.action.RequestProcessor 并覆蓋了里面的方法。

    sturts-config.xml  中 

    processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/> 通過 來替代

    org.apache.struts.action.RequestProcessor 的請求處理。

    public class LoginAction extends Action {
                //利用spring來注入這個對象。
                private LoginDao dao ;
                public void setDao(LoginDao dao) {
                System.out.println("執行注入");
                this.dao = dao;
                }
                public LoginDao getDao() {
                return dao;
                }
                public ActionForward execute(ActionMapping mapping, ActionForm form,
                HttpServletRequest request, HttpServletResponse response) {
                LoginForm loginForm = (LoginForm) form;// TODO Auto-generated method stub
                //這樣一改這行代碼似乎沒有必要了。
                //WebApplicationContext ctx = this.getWebApplicationContext();
                //LoginDao dao = (LoginDao) ctx.getBean("loginDao");
                User u = new User();
                u.setName(loginForm.getName());
                u.setPwd(loginForm.getPwd());
                //直接用dao來調用spring會將這個對象實例化。
                if(dao.checkLogin(u)){
                return mapping.findForward("success");
                }else{
                return  mapping.findForward("error");
                }
                }
                }
                這里的。
                LoginAction extends Action 說明 struts沒有和spring 耦合。
                看一下
                applicationContext.xml 中的配置。
                <beans>
                <bean id="loginDao" class="com.cao.dao.LoginDao"/>
                <bean name="/login" class="com.cao.struts.action.LoginAction">
                <property name="dao">
                <ref local="loginDao"/>
                </property>
                </bean>
                </beans>
                

    這里 name="/login" 與struts 中的path匹配

    class="com.cao.struts.action.LoginAction" 與struts 中的type匹配

    還要為 LoginAction 提供必要的setXXX方法。 獲得ApplicationCotext和依賴注入的工作都在DelegatingRequestProcessor中完成。

    3,全權委托:

    Action 的創建和對象的依賴注入全部由IOC容器來完成。使用Spring的DelegatingAcionProxy來幫助實現代理的工作

    org.springframework.web.struts.DelegatingActiongProxy繼承于org.apache.struts.action.Action .

    全權委托的配置方式同 方式 2 類似 (applcationContext.xml文件的配置和 Action類的實現方式相同)。

    <struts-config>
                <data-sources />
                <form-beans >
                <form-bean name="loginForm" 
      type="com.cao.struts.form.LoginForm" />
                </form-beans>
                <global-exceptions />
                <global-forwards />
                <action-mappings >
                <!-- type指向的是spring 的代理類 -->
                <action
                attribute="loginForm"
                input="login.jsp"
                name="loginForm"
                path="/login"
                scope="request"
                type="org.springframework.web.struts.DelegatingActionProxy" >
                <forward name="success" path="/ok.jsp" />
                <forward name="error" path="/error.jsp" />
                </action>
                </action-mappings>
                <message-resources parameter="com.cao.struts.ApplicationResources" />
                <plug-in className=
     "org.springframework.web.struts.ContextLoaderPlugIn">
                <set-property property="contextConfigLocation" 
      value="/WEB-INF/applicationContext.xml"/>
                </plug-in>
                </struts-config>
                不同之處
                1, <action>中 type指向的是spring 的代理類
                2, 去掉struts-config.xml中 <controller >
                


    三種整和方式中我們優先選用 全權委托的方式。

    理由:

    1,第一種使得過多的耦合了Spring和Action .

    2,RequestProcessor類已經被代理 如果要再實現自己的實現方式(如:編碼處理)怕有點麻煩。

    總結一下:

    整合工作中的步驟:

    1,修改struts-config.xml

    2, 配置applicationContext.xml

    3, 為Action添加get/set方法 來獲得依賴注入的功能。

    posted @ 2008-12-08 17:00 forgood 閱讀(170) | 評論 (0)編輯 收藏

    jQuery_AJAX學習

    JQUERY-AJAX學習

    posted @ 2008-12-03 00:03 forgood 閱讀(203) | 評論 (0)編輯 收藏

    jquery API學習(2)

       最近比較忙,但是每天網上還是的堅持學點,不積小流,無以成江河。
    今天學jQuery對象訪問:

    1.each(callback) 該方法以每一個匹配的元素作為上下文來執行一個函數,
    在每次執行函數時,都會給函數傳遞一個表示作為執行環境的元素在匹配的元素集合中所處位置的數字值作為參數(從0開始的int)
    返回‘false’將停止循環(相當于普通循環中使用的‘break’)
    返回‘true’將跳至下一個循環,(相當于在普通的循環中使用‘continue’)
    參數:callback(function)
    e.g1

    <img/><img/>
    jQuery代碼:
    $('img').each(function(){
    this.src="test"+i+".jpg";
    });

    e.g2

    <button>Change colors</button>
    <span></span>
    <div></div>
    <div></div>
    <div></div>
    <div></div>
    <div id="stop">Stop here</div>
    <div></div>
    <div></div>
    <div></div>
    

    jQuery代碼:

    $('button').click(function(){
        $('div').each(function(index,domEle){//domEle ==this
                $(domEle).css('backgroundColor',"yellow");
                if($(this).is("#stop")){
                    $("span").text("stopped at  div index #"+index);
                    return false;}
    });});

    2.size() 和length
    都可以勇于得到jQuery對象中元素的個數,
    返回: Number

    e.g1
    <img src="test1.jpg"/><img src="test2.jpg"/>
    jQuery代碼:
    $("img").size();

    e.g2
    同理:$("img").length;


    3.get()取得所有匹配的DOM元素集合
    返回:Array<Element>

    e.g1
    <img src="test1.jpg"/><img src="test2.jpg"/>
    jQuery代碼:
    $("img").get().reverse();
    result:
    [<img src="test1.jpg"/><img src="test2.jpg"/>]

    4.get(index)
    取得其中一個匹配元素,index表示取得第幾個匹配的元素
    返回值:Element
    HTML代碼:
    <img src="test1.jpg"/><img src="test2.jpg"/>
    jQuery代碼:
    $("img").get(0);
    result:
    [<img src="test1.jpg"/>]

    5.index(subject)
    搜索與參數表示的對象匹配的元素,并返回相應元素的索引值,
    如果哦找到了匹配的元素,從0開始返回;如果沒有找到匹配的元素,返回-1
    返回值;
    Number
    參數:
    subject(Element)
    e.g1返回id值為foobar的元素的索引值
    <div id="foobar"><div></div><div id="foo"></div></div>

    jQuery代碼:

    $("div").index($("#foobar")[0])   //0
    $("div").index($('#foo')[0]) // 2
    $("div").index($('#foo')) // -1




    備注:
    今天在瀏覽別人博客的時候看到的,收藏。

    有時候,我們頁面當中并不需要把要用到的JS全部加載出來,

    這會使頁面加載時速度變慢~~~如果能按需加載,那能提高不少性能...也能節約不少流量~~~給用戶帶來好的體驗~~

    好比說,當某個JS效果是觸發事件才顯示的...這個效果被封閉在一個JS中,,我想大家經常這樣做吧~~這時候,我們能按需加載那就不必在頁面載入時去加載JS文件~~~這在jquery插件中很多。

    用法:
    1 , 當在需要的時候再加載所需的javascript和css文件。
    $.include('file/test.js')或$.include('file/test.css')

    2,  當然若你一次想加載多個文件你也可以這樣寫:
    $.include(['file/test.js','file/test.css'])。

    3,  因為這兩個文件的路徑相同,所以可以先指定路徑再加載所有文件:
    $.ImportBasePath  = 'file/';
    $.include(['test.css','test.js']);

    4,  你還可以加載完文件后執行回調函數
    $.include("file/test.css",function(){
       alert("加載css后執行");
    });

    插件下載地址:
    http://www.94this.com.cn/myCode/jqueryIncludefile/jqueryIncludefile.rar

    注:jquery 自帶了有一個異步請求的方法,$.getScript ,可以異步加到JS并執行

    jQuery.getScript(url,[callback])

    通過 HTTP GET 請求載入并執行一個 JavaScript 文件。
    jQuery 1.2 版本之前,getScript 只能調用同域 JS 文件。 1.2中,您可以跨域調用 JavaScript 文件。注意:Safari 2 或更早的版本不能在全局作用域中同步執行腳本。如果通過 getScript 加入腳本,請加入延時函數。

     

    返回值

    XMLHttpRequest

    參數

    url (String) : 待載入 JS 文件地址。

    callback (Function) : (可選) 成功載入后回調函數。

    示例

    載入 jQuery 官方顏色動畫插件 成功后綁定顏色變化動畫。

    HTML 代碼:

    <button id="go">» Run</button>
    <div class="block"></div>

    jQuery 代碼:

    jQuery.getScript("http://dev.jquery.com/view/trunk/plugins/color/jquery.color.js",
    function(){
      $("#go").click(function(){
        $(".block").animate( { backgroundColor: 'pink' }, 1000)
          .animate( { backgroundColor: 'blue' }, 1000);
      });
    });

     

    加載并執行 test.js。

    jQuery 代碼:

    $.getScript("test.js");

     

    加載并執行 test.js ,成功后顯示信息。

    jQuery 代碼:

    $.getScript("test.js", function(){
      alert("Script loaded and executed.");
    });






    posted @ 2008-12-02 23:56 forgood 閱讀(803) | 評論 (0)編輯 收藏

    java和jsp中文件上傳

    jsp文件上傳大多采用采用開源項目來簡化處理,這里列出常用的兩個jar包的實現,并進行比較,說明他們的優缺點和應該注意的問題。

     Commons FileUpload,可以在http://jakarta.apache.org/commons/fileupload/下載,這個包需要Commons IO的支持,可以在http://jakarta.apache.org/commons/io/下載

     com.oreilly.servlet,可以在http://www.servlets.com/cos/下載
    Commons FileUpload提供三種文件上傳處理方式,DiskFileUpload、ServletFileUpload和PortletFileUpload三種方式,其中DiskFileUpload已經在javadoc下已經被標記為過期的方法,建議用ServletFileUpload代替,而PortletFileUpload需要配合portlet-api來使用,所以這里我們只介紹ServletFileUpload,并且這個也是最常用的。

    com.oreilly.servlet也提供了三種文件上傳的處理方式,MultipartWrapper、MultipartRequest和MultipartParser三種方式,其中MultipartWrapper和MultipartRequest的用法基本相同,并且沒有MultipartRequest提供的操作多,所以這里介紹MultipartRequest,MultipartParser和前兩者有些不同,可以用來處理某些特殊情況,例如表單中有兩個同名的文件上傳選擇框。

    我們暫時稱三面三種文件上傳方式分別為:ServletFileUpload方式(MultipartTestServlet)、MultipartRequest方式(MultipartTestServlet2)、MultipartParser方式(MultipartTestServlet3)

    代碼如下:
    test.html

    <%@ page language="java" import="java.util.*" contentType="text/html;charset=gbk" pageEncoding="gbk"%>
    <html>
      <body>
        <form action="MultipartTestServlet" enctype="multipart/form-data" method="post">
         <input type="text" name="username" /><br />
         <input type="file" name="myfile" /><br/>
         <input type="file" name="myfile" /><br/>
         <input type="submit" />
        </form>
        <br/><br/><br/><br/>
        <form action="MultipartTestServlet2" enctype="multipart/form-data" method="post">
         <input type="text" name="username" /><br />
         <input type="file" name="myfile" /><br/>
         <input type="file" name="myfile" /><br/>
         <input type="submit" />
        </form>
        <br/><br/><br/><br/>
        <form action="MultipartTestServlet3" enctype="multipart/form-data" method="post">
         <input type="text" name="username" /><br />
         <input type="file" name="myfile" /><br/>
         <input type="file" name="myfile" /><br/>
         <input type="submit" />
        </form>
      </body>
    </html>
    MultipartTestServlet.java

    package com.bug.servlet;

    import java.io.File;
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.FileUpload;
    import org.apache.commons.fileupload.FileUploadException;
    import org.apache.commons.fileupload.RequestContext;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.apache.commons.fileupload.servlet.ServletRequestContext;

    public class MultipartTestServlet extends HttpServlet {

     public MultipartTestServlet() {
      super();
     }

     public void doPost(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {

      request.setCharacterEncoding("gbk");
      RequestContext requestContext = new ServletRequestContext(request);
     
      if(FileUpload.isMultipartContent(requestContext)){
      
       DiskFileItemFactory factory = new DiskFileItemFactory();
       factory.setRepository(new File("c:/tmp/"));
       ServletFileUpload upload = new ServletFileUpload(factory);
       //upload.setHeaderEncoding("gbk");
       upload.setSizeMax(2000000);
       List items = new ArrayList();
        try {
         items = upload.parseRequest(request);
        } catch (FileUploadException e1) {
         System.out.println("文件上傳發生錯誤" + e1.getMessage());
        }

       Iterator it = items.iterator();
       while(it.hasNext()){
        FileItem fileItem = (FileItem) it.next();
        if(fileItem.isFormField()){     
         System.out.println(fileItem.getFieldName() + "   " + fileItem.getName() + "   " + new String(fileItem.getString().getBytes("iso8859-1"), "gbk"));
        }else{
         System.out.println(fileItem.getFieldName() + "   " +
            fileItem.getName() + "   " +
            fileItem.isInMemory() + "    " +
            fileItem.getContentType() + "   " +
            fileItem.getSize());
        
         if(fileItem.getName()!=null && fileItem.getSize()!=0){
          File fullFile = new File(fileItem.getName());
          File newFile = new File("c:/temp/" + fullFile.getName());
          try {
           fileItem.write(newFile);
          } catch (Exception e) {
           e.printStackTrace();
          }
         }else{
          System.out.println("文件沒有選擇 或 文件內容為空");
         }
        }
        
       }
      }
     }

    }

    MultipartTestServlet2.java

    package com.bug.servlet;

    import java.io.IOException;
    import java.util.Enumeration;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import com.oreilly.servlet.MultipartRequest;
    import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

    public class MultipartTestServlet2 extends HttpServlet {

     public MultipartTestServlet2() {
      super();
     }

     public void doPost(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {

      //request.setCharacterEncoding("gbk");  不起作用
      System.out.println("start ");
      MultipartRequest multi = new MultipartRequest(request, "c:/tmp/", 2*1024*1024, "gbk", new DefaultFileRenamePolicy());
      System.out.println("start ");
      Enumeration filesName = multi.getFileNames();
      Enumeration paramsName = multi.getParameterNames();
      while(paramsName.hasMoreElements()){
       String paramName = (String) paramsName.nextElement();
       System.out.println(multi.getParameter(paramName));
      }
      while(filesName.hasMoreElements()){
       String fileName = (String) filesName.nextElement();
       System.out.println(multi.getFilesystemName(fileName) + "  " +
              multi.getOriginalFileName(fileName) + "  " +
              multi.getContentType(fileName) + "  ");
       if(multi.getFilesystemName(fileName)!=null && !multi.getFilesystemName(fileName).equals(""))
        System.out.println(multi.getFile(fileName).toURI());
      }
     }
     
    }

    MultipartTestServlet3.java

    package com.bug.servlet;

    import java.io.File;
    import java.io.IOException;

    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import com.oreilly.servlet.multipart.FilePart;
    import com.oreilly.servlet.multipart.MultipartParser;
    import com.oreilly.servlet.multipart.ParamPart;
    import com.oreilly.servlet.multipart.Part;

    public class MultipartTestServlet3 extends HttpServlet {

     public MultipartTestServlet3() {
      super();
     }

     public void doPost(HttpServletRequest request, HttpServletResponse response)
       throws ServletException, IOException {

          MultipartParser mp = new MultipartParser(request, 2*1024*1024, false, false, "gbk");
          Part part;
          while ((part = mp.readNextPart()) != null) {
            String name = part.getName();
            if (part.isParam()) {
              ParamPart paramPart = (ParamPart) part;
              String value = paramPart.getStringValue();
              System.out.println("param: name=" + name + "; value=" + value);
            }
            else if (part.isFile()) {
              // it's a file part
              FilePart filePart = (FilePart) part;
              String fileName = filePart.getFileName();
              if (fileName != null) {
                long size = filePart.writeTo(new File("c:/tmp/"));
                System.out.println("file: name=" + name + "; fileName=" + fileName +
                  ", filePath=" + filePart.getFilePath() +
                  ", contentType=" + filePart.getContentType() +
                  ", size=" + size);
              }
              else {
               System.out.println("file: name=" + name + "; EMPTY");
              }
              System.out.flush();
            }
          }
        }

    }

    web.xml中加入

     <servlet>
        <servlet-name>MultipartTestServlet</servlet-name>
        <servlet-class>com.bug.servlet.MultipartTestServlet</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>MultipartTestServlet2</servlet-name>
        <servlet-class>com.bug.servlet.MultipartTestServlet2</servlet-class>
      </servlet>
      <servlet>
        <servlet-name>MultipartTestServlet3</servlet-name>
        <servlet-class>com.bug.servlet.MultipartTestServlet3</servlet-class>
      </servlet>
      <servlet-mapping>
        <servlet-name>MultipartTestServlet</servlet-name>
        <url-pattern>/MultipartTestServlet</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>MultipartTestServlet2</servlet-name>
        <url-pattern>/MultipartTestServlet2</url-pattern>
      </servlet-mapping>
      <servlet-mapping>
        <servlet-name>MultipartTestServlet3</servlet-name>
        <url-pattern>/MultipartTestServlet3</url-pattern>
      </servlet-mapping>

    問題1、中文問題:
     三種凡是都可以通過自己的方法來設置encoding為gbk開處理和解決中文問題,包括初始化的時候傳入gbk作為參數,或是是初始化后通過setEncoding的方式來實現。
     另外ServletFileUpload方式也可以通過request.setCharacterEncoding("gbk");的方式來實現,而其它兩種方式不支持這種方式。


    問題2、文件大小限制
     ServletFileUpload方式可以設置文件大小限制,也可以不用設置,例子中的upload.setSizeMax(2000000)就可以注釋掉。如果設置upload.setSizeMax(-1),表明不限制上傳的大小。文檔中沒有指明默認的限制的多少,我在不設置的情況下上傳了一個9M的東西,可以上傳,估計默認是不限制大小的。
     而MultipartRequest方式和MultipartParser方式是必須設置文件的上傳文件的大小限制的,如果不設置,默認是1M的大小限制。


    問題3、文件上傳發生錯誤
     如果文件上傳過程中發生任何錯誤,或者是文件的大小超出了范圍,系統都將拋出錯誤。
     ServletFileUpload方式在upload.parseRequest(request)時拋出錯誤
     MultipartRequest方式在new MultipartRequest(。。。)時拋出錯誤
     MultipartParser方式在new MultipartParser(。。。)時拋出錯誤


    問題4、上傳同名文件時,他們保存到臨時目錄是的沖突問題
     ServletFileUpload方式,不會有沖突,系統會把上傳得文件按照一定的規則重新命名,保證不會沖突
     MultipartParser方式,會產生沖突,系統會把文件按照上傳時的文件名,保存到臨時目錄下,如果兩個用會同時上傳文件名相同的文件,那么就可能會產生沖突,一方把另一方的臨時文件給替換了。
     MultipartRequest方式,在初始化時如果提供了一個名稱轉換策略,就不會有沖突,如果不提桶,就會有沖突。在上面的例子中我們提供了一個new DefaultFileRenamePolicy()保證了文件名不會有沖突發生。


    問題5:表單中有兩個同名的文件上傳選擇框,就像我們例子中的myfile一樣,每個表單中有兩個name=“myfile”的上傳框
     ServletFileUpload方式,可以處理,可以分別得到他們各自的文件,
     MultipartRequest方式,不可以處理,會發生沖突,會有一個上傳框的文件覆蓋了另外一個。
     MultipartParser方式,可以處理,可以分別得到他們各自的文件,


    備注:
     代碼比較亂,主要是為了說明他們間的區別。他們的詳細地使用說明還是要參考他的javadoc和domo。

    參考:
     1、http://www.servlets.com/cos/#classes
     2、http://jakarta.apache.org/commons/fileupload/apidocs/index.html
     3、http://jakarta.apache.org/commons/fileupload/using.html
     4、http://www.onjava.com/pub/a/onjava/2003/06/25/commons.html?page=3

    posted @ 2008-12-01 18:19 forgood 閱讀(608) | 評論 (0)編輯 收藏

    oracle中的鎖表語句

    //先鎖表,然后再判斷是否已經存在數據,以防止出現重復行
       String lockSql = "update YHZHMX set YHZHMX_DJBH=YHZHMX_DJBH where 1=2";
    //上面的語法貌似不好用.故采用下面的語法
       lockSql = "SELECT * FROM YHZHMX FOR UPDATE";

    posted @ 2008-12-01 11:47 forgood 閱讀(593) | 評論 (0)編輯 收藏

    jquery API學習(1)

    一、jquery核心函數的學習

    1、jQuery(exp,[context]),這個函數接受一個包含css選擇器的字符串,然后用這個字符串去匹配一組元素,通俗的講,exp參數是要匹配的表達式,context是匹配的范圍,可以是dom元素,文檔或者jquery對象。
    jQuery的核心功能都是通過這個函數實現的,
    例子:
    a.找到所有p元素,并且這些元素都是div元素的子元素
    HTML代碼:<p>guoxzh</p><div><p>guoxiaozheng</p></div><p>guoxzh</p.

    jQuery代碼:$("div>p")

    b.在文檔的第一個表單中,查找所有的當選按鈕

    HTML代碼:是帶有type值為radio的input元素
    JQuery代碼:$("input:radio",document.forms[0]);

    c.在一個有AJAX返回的xml文檔中,查找所有的div元素

    $("div",xml.responseXML);

    2.jQuery(html)根據提供的原始的HTMl標記字符串,動態創建有jQuery對象包含的Dom元素,你可以傳遞一個手寫的 HTML 字符串,或者由某些模板引擎或插件創建的字符串,也可以是通過 AJAX 加載過來的字符串。但是在你創建 input 元素的時會有限制,可以參考第二個示例。當然這個字符串可以包含斜杠 (比如一個圖像地址),還有反斜杠。當你創建單個元素時,請使用閉合標簽或 XHTML 格式。例如,創建一個 span ,可以用 $("<span/>") 或 $("<span></span>") ,但不推薦 $("<span>");
    返回值:
        JQuery
    參數:
       用于動態創建dom元素的HTML標簽的字符串,

    例子:
    a.動態創建一個div元素,追加到body里
    jQuery代碼:
    $("<div><input type="text" name="name" value=""></div>").appendTo("body");

    b.創建一個<input>元素必須同時設定type屬性,
    jQuery代碼:
    IE中無效

    $("<input>").attr("type","checkbox");

    在IE中有效

    $("<input type='checkbox'>");

    3.jQuery(element)將一個或多個元素DOM元素轉化為jQuery對象
    這個函數也可以接收XML文檔和Window對象(雖然它們不是DOM元素)作為有效的參數。

    返回值:jQuery

    例子:
    a.設置頁面的背景色
    jQuery代碼:
    $("document.body").css("background","black");

    b.隱藏一個表單中所有元素
    jQuery代碼:
    $("myForm.elements").hide();

    posted @ 2008-11-30 15:48 forgood 閱讀(562) | 評論 (0)編輯 收藏

    jquery學習網站

    jquery官方網站
    http://jquery.com/

    jquery中文學習網站
    http://jquery.com/

    posted @ 2008-11-30 14:40 forgood 閱讀(203) | 評論 (1)編輯 收藏

    Java棧與堆

    Java棧與堆

    ----對這兩個概念的理解總是忘記,今天從網上搜到一篇比較好的文章收藏

    1. 棧(stack)與堆(heap)都是Java用來在Ram中存放數據的地方。與C++不同,Java自動管理棧和堆,程序員不能直接地設置棧或堆。

    2. 棧的優勢是,存取速度比堆要快,僅次于直接位于CPU中的寄存器。但缺點是,存在棧中的數據大小與生存期必須是確定的,缺乏靈活性。另外,棧數據可以共享,詳見第3點。堆的優勢是可以動態地分配內存大小,生存期也不必事先告訴編譯器,Java的垃圾收集器會自動收走這些不再使用的數據。但缺點是,由于要在運行時動態分配內存,存取速度較慢。

    3. Java中的數據類型有兩種。

    一種是基本類型(primitive types), 共有8種,即int, short, long, byte, float, double, boolean, char(注意,并沒有string的基本類型)。這種類型的定義是通過諸如int a = 3; long b = 255L;的形式來定義的,稱為自動變量。值得注意的是,自動變量存的是字面值,不是類的實例,即不是類的引用,這里并沒有類的存在。如int a = 3; 這里的a是一個指向int類型的引用,指向3這個字面值。這些字面值的數據,由于大小可知,生存期可知(這些字面值固定定義在某個程序塊里面,程序塊退出后,字段值就消失了),出于追求速度的原因,就存在于棧中。

    另外,棧有一個很重要的特殊性,就是存在棧中的數據可以共享。假設我們同時定義:
    復制內容到剪貼板代碼:
    int a = 3;
    int b = 3;
    編譯器先處理int a = 3;首先它會在棧中創建一個變量為a的引用,然后查找有沒有字面值為3的地址,沒找到,就開辟一個存放3這個字面值的地址,然后將a指向3的地址。接著處理int b = 3;在創建完b的引用變量后,由于在棧中已經有3這個字面值,便將b直接指向3的地址。這樣,就出現了a與b同時均指向3的情況。

    特別注意的是,這種字面值的引用與類對象的引用不同。假定兩個類對象的引用同時指向一個對象,如果一個對象引用變量修改了這個對象的內部狀態,那么另一個對象引用變量也即刻反映出這個變化。相反,通過字面值的引用來修改其值,不會導致另一個指向此字面值的引用的值也跟著改變的情況。如上例,我們定義完a與b的值后,再令a=4;那么,b不會等于4,還是等于3。在編譯器內部,遇到a=4;時,它就會重新搜索棧中是否有4的字面值,如果沒有,重新開辟地址存放4的值;如果已經有了,則直接將a指向這個地址。因此a值的改變不會影響到b的值。

    另一種是包裝類數據,如Integer, String, Double等將相應的基本數據類型包裝起來的類。這些類數據全部存在于堆中,Java用new()語句來顯示地告訴編譯器,在運行時才根據需要動態創建,因此比較靈活,但缺點是要占用更多的時間。 4. String是一個特殊的包裝類數據。即可以用String str = new String("abc");的形式來創建,也可以用String str = "abc";的形式來創建(作為對比,在JDK 5.0之前,你從未見過Integer i = 3;的表達式,因為類與字面值是不能通用的,除了String。而在JDK 5.0中,這種表達式是可以的!因為編譯器在后臺進行Integer i = new Integer(3)的轉換)。前者是規范的類的創建過程,即在Java中,一切都是對象,而對象是類的實例,全部通過new()的形式來創建。Java中的有些類,如DateFormat類,可以通過該類的getInstance()方法來返回一個新創建的類,似乎違反了此原則。其實不然。該類運用了單例模式來返回類的實例,只不過這個實例是在該類內部通過new()來創建的,而getInstance()向外部隱藏了此細節。那為什么在String str = "abc";中,并沒有通過new()來創建實例,是不是違反了上述原則?其實沒有。

    5. 關于String str = "abc"的內部工作。Java內部將此語句轉化為以下幾個步驟:

    (1)先定義一個名為str的對String類的對象引用變量:String str;

    (2)在棧中查找有沒有存放值為"abc"的地址,如果沒有,則開辟一個存放字面值為"abc"的地址,接著創建一個新的String類的對象o,并將o的字符串值指向這個地址,而且在棧中這個地址旁邊記下這個引用的對象o。如果已經有了值為"abc"的地址,則查找對象o,并返回o的地址。

    (3)將str指向對象o的地址。

    值得注意的是,一般String類中字符串值都是直接存值的。但像String str = "abc";這種場合下,其字符串值卻是保存了一個指向存在棧中數據的引用!

    為了更好地說明這個問題,我們可以通過以下的幾個代碼進行驗證。
    復制內容到剪貼板代碼:
    String str1 = "abc";
    String str2 = "abc";
    System.out.println(str1==str2); //true
    注意,我們這里并不用str1.equals(str2);的方式,因為這將比較兩個字符串的值是否相等。==號,根據JDK的說明,只有在兩個引用都指向了同一個對象時才返回真值。而我們在這里要看的是,str1與str2是否都指向了同一個對象。
    結果說明,JVM創建了兩個引用str1和str2,但只創建了一個對象,而且兩個引用都指向了這個對象。

    我們再來更進一步,將以上代碼改成:
    復制內容到剪貼板代碼:
    String str1 = "abc";
    String str2 = "abc";
    str1 = "bcd";
    System.out.println(str1 + "," + str2); //bcd, abc
    System.out.println(str1==str2); //false
    這就是說,賦值的變化導致了類對象引用的變化,str1指向了另外一個新對象!而str2仍舊指向原來的對象。上例中,當我們將str1的值改為"bcd"時,JVM發現在棧中沒有存放該值的地址,便開辟了這個地址,并創建了一個新的對象,其字符串的值指向這個地址。

    事實上,String類被設計成為不可改變(immutable)的類。如果你要改變其值,可以,但JVM在運行時根據新值悄悄創建了一個新對象,然后將這個對象的地址返回給原來類的引用。這個創建過程雖說是完全自動進行的,但它畢竟占用了更多的時間。在對時間要求比較敏感的環境中,會帶有一定的不良影響。

    再修改原來代碼:
    復制內容到剪貼板代碼:
    String str1 = "abc";
    String str2 = "abc";

    str1 = "bcd";

    String str3 = str1;
    System.out.println(str3); //bcd

    String str4 = "bcd";
    System.out.println(str1 == str4); //true
    str3這個對象的引用直接指向str1所指向的對象(注意,str3并沒有創建新對象)。當str1改完其值后,再創建一個String的引用str4,并指向因str1修改值而創建的新的對象。可以發現,這回str4也沒有創建新的對象,從而再次實現棧中數據的共享。

    我們再接著看以下的代碼。
    復制內容到剪貼板代碼:
    String str1 = new String("abc");
    String str2 = "abc";
    System.out.println(str1==str2); //false 創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。

    String str1 = "abc";
    String str2 = new String("abc");
    System.out.println(str1==str2); //false
    創建了兩個引用。創建了兩個對象。兩個引用分別指向不同的兩個對象。

    以上兩段代碼說明,只要是用new()來新建對象的,都會在堆中創建,而且其字符串是單獨存值的,即使與棧中的數據相同,也不會與棧中的數據共享。

    6. 數據類型包裝類的值不可修改。不僅僅是String類的值不可修改,所有的數據類型包裝類都不能更改其內部的值。
    7. 結論與建議:

    (1)我們在使用諸如String str = "abc";的格式定義類時,總是想當然地認為,我們創建了String類的對象str。擔心陷阱!對象可能并沒有被創建!唯一可以肯定的是,指向String類的引用被創建了。至于這個引用到底是否指向了一個新的對象,必須根據上下文來考慮,除非你通過new()方法來顯要地創建一個新的對象。因此,更為準確的說法是,我們創建了一個指向String類的對象的引用變量str,這個對象引用變量指向了某個值為"abc"的String類。清醒地認識到這一點對排除程序中難以發現的bug是很有幫助的。

    (2)使用String str = "abc";的方式,可以在一定程度上提高程序的運行速度,因為JVM會自動根據棧中數據的實際情況來決定是否有必要創建新對象。而對于String str = new String("abc");的代碼,則一概在堆中創建新對象,而不管其字符串值是否相等,是否有必要創建新對象,從而加重了程序的負擔。這個思想應該是享元模式的思想,但JDK的內部在這里實現是否應用了這個模式,不得而知。

    (3)當比較包裝類里面的數值是否相等時,用equals()方法;當測試兩個包裝類的引用是否指向同一個對象時,用==。

    (4)由于String類的immutable性質,當String變量需要經常變換其值時,應該考慮使用StringBuffer類,以提高程序效率。

    posted @ 2008-11-30 14:29 forgood 閱讀(186) | 評論 (0)編輯 收藏

    java中壓縮與解壓縮的實現

         摘要: 壓縮的 import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import...  閱讀全文

    posted @ 2008-09-16 20:52 forgood 閱讀(179) | 評論 (0)編輯 收藏

    JAVA解析XML配置文件的讀取操作

    現在關鍵是如何讀取XML配置文件?有好幾種XML解析器:主要有DOM和SAX ,這些區別網上文章介紹很多。

        在apache的XML項目組中,目前有Xerces Xalan Cocoon幾個開發XML相關技術的project.Tomcat本身使用的是 Sun 的 JAXP,而其XSL Taglib project中使用Xerces解析器。

        好了,上面都是比較煩人的理論問題,還是趕快切入XML的配置文件的讀取吧。

        在我們的程序中,通常要有一些根據主機環境確定的變量。比如數據庫訪問用戶名和密碼,不同的主機可能設置不一樣。只要更改XML配置文件,就可以正常運行。


    localhost
    sqlname
    username
    password

        上面這個myenv.xml配置文件一般是放在tomcat的WEB-INF/classes目錄下.

        我們編制一個Java程序直接讀取,將dbhost dbuser dbpassword提取出來供其他程序訪問數據庫用.

        目前使用SAX比較的多,與DOM主要區別是 SAX是一行一行讀取XML文件進行分析,適合比較大文件,DOM是一次性讀入內存,顯然不能對付大文件.這里我們使用SAX解析,由于SAX解析器不斷在發展,網上有不少文章是針對老版本的.如果你使用JDK1.4 ,可以參考 使用SAX處理XML文檔 一文.這里的程序是根據其改進并且經過實踐調試得來的.

    對上面myenv.xml讀取的Java程序:


    import org.xml.sax.Attributes;
    import org.xml.sax.helpers.DefaultHandler;
    import org.xml.sax.SAXException;
    import java.util.Properties;

    //使用DefaultHandler的好處 是 不必陳列出所有方法,
    public class ConfigParser extends DefaultHandler {

    ////定義一個Properties 用來存放 dbhost dbuser dbpassword的值
    private Properties props;

    private String currentSet;
    private String currentName;
    private StringBuffer currentValue = new StringBuffer();

    //構建器初始化props
    public ConfigParser() {

    this.props = new Properties();
    }

    public Properties getProps() {
    return this.props;
    }

    //定義開始解析元素的方法. 這里是將 中的名稱xxx提取出來.
    public void startElement(String uri, String localName, String qName, Attributes attributes)
    throws SAXException {
    currentValue.delete(0, currentValue.length());
    this.currentName =qName;

    }

    //這里是將 之間的值加入到currentValue

    public void characters(char[] ch, int start, int length) throws SAXException {

    currentValue.append(ch, start, length);

    }

    //在遇到 結束后,將之前的名稱和值一一對應保存在props中

    public void endElement(String uri, String localName, String qName) throws SAXException {

    props.put(qName.toLowerCase(), currentValue.toString().trim());
    }

    }

        上面的這個解析程序比較簡單吧? 其實解析XML就是這么簡單.

        現在我們已經將dbhost dbuser dbpassword的值localhost sqlname username password提取了出來.但是這只是在在解析器內部,我們的程序還不能訪問.需要再編制一個程序.


    import java.util.Properties;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    import java.net.URL;

    public class ParseXML{

    //定義一個Properties 用來存放 dbhost dbuser dbpassword的值
    private Properties props;

    //這里的props
    public Properties getProps() {
    return this.props;
    }

    public void parse(String filename) throws Exception {

    //將我們的解析器對象化
    ConfigParser handler = new ConfigParser();

    //獲取SAX工廠對象
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setNamespaceAware(false);
    factory.setValidating(false);

    //獲取SAX解析
    SAXParser parser = factory.newSAXParser();

    //得到配置文件myenv.xml所在目錄. tomcat中是在WEB-INF/classes
    //下例中BeansConstants是用來存放xml文件中配置信息的類,可以自己代替或定義
    URL confURL = BeansConstants.class.getClassLoader().getResource(filename);

    try
    {
    //將解析器和解析對象myenv.xml聯系起來,開始解析
    parser.parse(confURL.toString(), handler);
    //獲取解析成功后的屬性 以后 我們其他應用程序只要調用本程序的props就可以提取出屬性名稱和值了
    props = handler.getProps();
    }finally{
    factory=null;
    parser=null;
    handler=null;
    }

    }

    }

        由于我們的XML文件是使用最簡單的形式 ,因此解析器相對簡單,但是這已經足夠對付我們的配置文件了.

        判斷一個程序系統的先進性,我們先看看他的配置文件,如果還在使用老套的xxx=123 這樣類似.ini的文件,

    posted @ 2008-09-09 12:49 forgood 閱讀(396) | 評論 (0)編輯 收藏

    主站蜘蛛池模板: 999在线视频精品免费播放观看| 国产午夜免费高清久久影院| 九一在线完整视频免费观看| 一级特黄录像免费播放肥| 在线涩涩免费观看国产精品| 最近最新高清免费中文字幕 | 国产一区在线观看免费| 亚洲国产天堂久久久久久| 亚洲真人无码永久在线| 亚洲色图.com| 亚洲AV无码成人网站在线观看| 国产精品极品美女自在线观看免费 | 亚洲AV本道一区二区三区四区| 亚洲av片不卡无码久久| 老湿机一区午夜精品免费福利 | 巨胸狂喷奶水视频www网站免费| 久久中文字幕免费视频| 在线免费观看中文字幕| 在线精品亚洲一区二区小说| 666精品国产精品亚洲| 久久精品国产亚洲AV电影网| 三根一起会坏掉的好痛免费三级全黄的视频在线观看 | 亚洲情a成黄在线观看| 久久精品亚洲一区二区三区浴池 | 日韩电影免费在线观看视频 | 亚洲人成网77777色在线播放| 亚洲大片免费观看| 深夜a级毛片免费无码| 性色午夜视频免费男人的天堂| 啦啦啦在线免费视频| 久久亚洲伊人中字综合精品| 亚洲欧美国产欧美色欲| a视频在线免费观看| 手机在线毛片免费播放| 亚洲精品乱码久久久久久久久久久久| 亚洲人成免费电影| 国产免费MV大全视频网站| 日韩欧美一区二区三区免费观看| 国产亚洲色婷婷久久99精品91| 亚洲a级成人片在线观看| 三级网站在线免费观看|