ricegun

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            2 Posts :: 4 Stories :: 3 Comments :: 0 Trackbacks

          2010年8月4日 #

          背景知識:
          從JDK5開始提供名為Annotation(注釋)的功能,它被定義為JSR-175規范。注釋是以“@注釋名”在代碼中存在的,還可以添加一些參數值,例如:@SuppressWarnings(value="unchecked")。注釋可以附加在package, class, method, field等上面,相當于給它們添加了額外的輔助信息,我們可以通過反射機制編程實現對這些元數據的訪問。如果沒有外部解析工具等對其加以解析和處理的情況,本身不會對Java的源代碼或class文件等產生任何影響,也不會對它們的執行產生任何影響。
          元數據的作用,大致可分為三種:編寫文檔,通過代碼里標識的元數據生成文檔;代碼分析,通過代碼里標識的元數據對代碼進行分析;編譯檢查,通過代碼里標識的元數據讓編譯器能實現基本的編譯檢查。
          JDK5內置的基本注釋
          JDK5內置了一些常用的注釋,可以在編譯時幫我們捕獲部分編譯錯誤,及提示信息,下面介紹下這些注釋的用法:
          1、@Override定義在java.lang.Override中,此注釋只適用于修辭方法,表示一個方法聲明打算重寫超類中的另一個方法聲明。如果方法利用此注釋類型進行注解但沒有重寫超類方法,則編譯器會生成一條錯誤消息。例如我們為某類重寫toString()方法卻寫成了tostring(),并且我們為該方法添加了@Override注釋;代碼如下:
          public class OverrideDemo {
              @Override
          public String tostring() {
                  return super.toString();
              }
          }
          在編譯時,會提示以下錯誤信息:
          OverrideTest.java:4: 方法未覆蓋其父類的方法
                  @Override
                   ^1 錯誤
          2、@Deprecated定義在java.lang.Deprecated中,此注釋可用于修辭方法、屬性、類,表示不鼓勵程序員使用這樣的元素,通常是因為它很危險或存在更好的選擇。在使用不被贊成的程序元素或在不被贊成的代碼中執行重寫時,編譯器會發出警告。使用@Deprecated的示例代碼如下:
          public class DeprecatedDemo {
              public static void main(String[] args) {
                   DeprecatedClass.DeprecatedMethod();
              }
          }
           
          class DeprecatedClass {
              @Deprecated
              public static void DeprecatedMethod() {
                  // TODO
              }
          }
          在編譯時,會得到以下提示信息:
          注意:DeprecatedDemo.java 使用或覆蓋了已過時的 API
          注意:要了解詳細信息,請使用 -Xlint:deprecation 重新編譯。
          如果在編譯時添加-Xlint:deprecation參數,我們能更清楚的看到該警告的詳細信息,如下:
          DeprecatedDemo.java:6: 警告:[deprecation] SomeClass 中的 DeprecatedMethod() 已過時
                          SomeClass.DeprecatedMethod();
                                   ^1 警告
          要注意@Deprecated與@deprecated的區別,@deprecated是為了生成文檔的需要,例如:
          class DeprecatedClass {
                  /**
          * @deprecated 此方法已過時,不建議使用
          */
          @Deprecated
              public static void DeprecatedMethod() {
                  // TODO
              }
          }
           3、@SuppressWarnings定義在java.lang.SuppressWarnings中,用來抑制編譯時的警告信息。與前兩個注釋有所不同,你需要添加一個參數才能正確使用,這些參數值都是已經定義好了的,我們選擇性的使用就好了,參數如下:
          參數
          說明
          deprecation
          使用了過時的類或方法時的警告
          unchecked
          執行了未檢查的轉換時的警告,例如當使用集合時沒有用泛型 (Generics) 來指定集合保存的類型
          fallthrough
          當 Switch 程序塊直接通往下一種情況而沒有 Break 時的警告
          path
          在類路徑、源文件路徑等中有不存在的路徑時的警告
          serial
          當在可序列化的類上缺少 serialVersionUID 定義時的警告
          finally
          任何 finally 子句不能正常完成時的警告
          all
          關于以上所有情況的警告
          通過上面的表格,你應該了解到每個參數的用意了,下面我就以一個常用的參數unchecked為例,為你展示如何使用@SuppressWarnings注釋,示例代碼如下:
          import java.util.List;
          import java.util.ArrayList;
          public class SuppressWarningsDemo {
                  public static List cache = new ArrayList();
                  //@SuppressWarnings(value = "unchecked")
                  public void add(String data) {
                      cache.add(data);
                  }
          }
          當我們不使用@SuppressWarnings注釋時,編譯器就會有如下提示:
          注意:SuppressWarningsDemo.java 使用了未經檢查或不安全的操作。
          注意:要了解詳細信息,請使用 -Xlint:unchecked 重新編譯。
          下面我們去掉@SuppressWarnings(value="unchecked")這一行的注釋符“//”,它會屏蔽編譯時的警告信息,這也就是它所要達到的目的。
                 另外,由于@SuppressWarnings注釋只有一個參數,并且參數名為value,所以我們可以將上面一句注釋簡寫為@SuppressWarnings("unchecked");
          同時參數value可以取多個值如:@SuppressWarnings(value={"unchecked", "deprecation"})
          或@SuppressWarnings({"unchecked", "deprecation"})。
          自定義Annotation注釋
          1、注釋annotation與接口的異同:
          因為annotation類型是一個非凡的接口,所以它與接口之間存在著某些差異:
          A.       Annotation類型使用關鍵字@interface而不是interface,這個關鍵字聲明隱含了一個信息,它是繼承了java.lang.annotation.Annotation接口,并非聲明了一個interface。
          B.        Annotation類型的方法定義是獨特的、受限制的,方法必須聲明為無參數、無異常拋出的。這些方法定義了annotation的成員:方法名成為了成員名,而方法返回值成為了成員的類型。而方法返回值類型必須為primitive類型、Class類型、枚舉類型、annotation類型或者由前面類型之一作為元素的一維數組。方法的后面可以使用default和一個默認數值來聲明成員的默認值,null不能作為成員默認值,這與我們在非annotation類型中定義方法有很大不同。
          C.       Annotation類型又與接口有著近似之處,它們可以定義常量、靜態成員類型(比如枚舉類型定義)。Annotation類型也可以如接口一般被實現或者繼承。
          2、自定義注釋的實例:
          下面,我們將看到如何定義annotation類型的例子。它展示了annotation類型聲明以及@interface與interface之間的不同:
          import java.lang.annotation.*;
          /**
          使用annotation來描述那些被標注的成員是不穩定的,需要更改
          */
          public @interface Unstable {
          }
          下面的另一個例子只定義了一個成員。并通過將這個成員命名為value,使我們可以方便的使用這種annotation的快捷聲明方式:
          /**
          使用Author這個annotation定義在程序中指出代碼的作者
          */
          public @interface Author {
               /** 
          返回作者名 */
               String value();
          }
          以下的例子更加復雜。Reviews annotation類型只有一個成員,但是這個成員的類型是復雜的:由Review annotation組成的數組。Review annotation類型有3個成員:枚舉類型成員grade、表示Review名稱的字符串類型成員Reviewer、具有默認值的字符串類型成員 Comment。
          /**
          * Reviews annotation
          類型只有一個成員,
          但是這個成員的類型是復雜的:由Review annotation組成的數組
          */
          @Retention(RetentionPolicy.RUNTIME)
          public @interface Reviews {
              Review[] value();
          }
          /**
          * Review annotation
          類型有3個成員: 
          枚舉類型成員grade
          表示Review名稱的字符串類型成員Reviewer
          具有默認值的字符串類型成員Comment
          */
          public @interface Review {
              // 
          內嵌的枚舉類型
               public static enum Grade { EXCELLENT, SATISFACTORY, UNSATISFACTORY };
               // 
          下面的方法定義了annotation的成員
               Grade grade();
               String reviewer();
               String comment() default "";
          }
          最后,我們來定義一個annotation方法用于羅列出類運行中所有的unchecked異常。這個 annotation類型將一個數組作為了唯一的成員。數組中的每個元素都是異常類。為了加強對未檢查的異常(此類異常都是在運行時拋出)進行報告,我們可以在代碼中對異常的類型進行限制:
          public @interface UncheckedExceptions { 
               Class<? extends RuntimeException>[] value();
          }
          Meta-Annotation類型
          Annotation 類型可以被它們自己所標注。Java5.0定義了4個標準的meta-annotation類型,分別是:Target、Retention、Documented、Inherited,它們被用來提供對其它annotation類型作說明。 這些類型和它們所支持的類在java.lang.annotation包中可以找到。
          @Target的用法:指示注釋類型所適用的程序元素的種類。如果注釋類型聲明中不存在 Target 元注釋,則聲明的類型可以用在任一程序元素上。如果存在這樣的元注釋,則編譯器強制實施指定的使用限制。例如,以下這個注釋只能用來聲明方法
          @Target(ElementType.METHOD)
              public @interface MyAnnotation {
                  ... 
              }
          java.lang.annotation.ElementType是一個枚舉類型,它具有以下定義:
          ElementType
          說明
          ElementType.ANNOTATION_TYPE
          應用于注釋類型聲明
          ElementType.CONSTRUCTOR
          構造方法聲明
          ElementType.FIELD
          應用于字段聲明(包括枚舉常量)
          ElementType.LOCAL_VARIABLE
          應用于局部變量聲明
          ElementType.METHOD
          應用于方法聲明
          ElementType.PACKAGE
          應用于包聲明
          ElementType.PARAMETER
          應用于參數聲明
          ElementType.TYPE
          應用于類、接口(包括注釋類型)或枚舉聲明
           @Retention的用法指示注釋類型的注釋要保留多久。如果注釋類型聲明中不存在 Retention 注釋,則保留策略默認為 RetentionPolicy.CLASS,例如:
          @ Retention(RetentionPolicy.CLASS)
              public @interface MyAnnotation {
                  ... 
              }
                 java.lang.annotation.RetentionPolicy是一個枚舉類型,它具有以下定義:
          RetentionPolicy
          說明
          RetentionPolicy.CLASS
          編譯器將把注釋記錄在類文件中,但在運行時 VM 不需要保留注釋
          RetentionPolicy.RUNTIME
          編譯器將把注釋記錄在類文件中,在運行時 VM 將保留注釋,因此可以反射性地讀取
          RetentionPolicy.SOURCE
          編譯器要丟棄的注釋
          @Documented的用法:指示某一類型的注釋將通過 javadoc 和類似的默認工具進行文檔化。應使用此類型來注釋這些類型的聲明:其注釋會影響由其客戶端注釋的元素的使用。如果類型聲明是用 Documented 來注釋的,則其注釋將成為注釋元素的公共 API 的一部分。Documented是一個沒有成員的注釋。
          @Inherited的用法:指示注釋類型自動被子類繼承。 Inherited是一個沒有成員的注釋。
          注意,如果使用@Inherited注釋類以外的任何事物都是無效的。還要注意,此元注釋僅對從超類繼承注釋有效;對已實現接口的注釋無效。
          posted @ 2010-08-04 10:22 第七日 閱讀(384) | 評論 (0)編輯 收藏

          2007年1月5日 #

          怎么用 javascript 做數據的格式化

          ?

          作者:老 K

          ???????? 我們在項目中都有用過金額數字及日期等數據格式化輸出顯示,比如前面加上“¥”,數值取小數點后兩位,短日期時間等。一般的高級語言及開發工具都有提供相應的轉換函數如 format 之類,可是我在最近做 web 網上銀行相關的系統時,卻遇到這個很麻煩的問題,就是 javascript 不提供這種 format 函數,查了些資料,知道 vbscript 是有格式化函數的,可是 vbscript 是微軟專用的,無奈只好用正則表達式,可正則表達式也不能夠很通用地解決各種類型轉換問題,真的是很郁悶,無意中找到看到一個 AJAX 開發工具的演示(工具下載地址是點擊鏈接),看到它的數據有顯示“¥”和數值小數點后兩位格式化,馬上下載了看了下,發現它居然是用 javascript+XSL 實現了通用的格式化函數,下載 AJAX WebShop 后,我找到它的 system.js 這個文件,打開找到以下函數:

          function FormatFloat(value,mask)

          {

          ???????? return BasicFormat(value,mask,'FormatNumber')

          }

          function FormatDate(varDate, bstrFormat, varDestLocale)

          {

          ???????? return BasicFormat(varDate,bstrFormat,'FormatDate',varDestLocale);

          }

          function FormatTime(varTime, bstrFormat, varDestLocale)

          {

          ???????? return BasicFormat(varTime,bstrFormat,'FormatTime',varDestLocale);

          }

          function BasicFormat(value,mask,action,param)

          {

          ???????? var xmlDoc;

          ???????? var xslDoc;

          ???????? var v=''+value+''+mask+'';

          ???????? xmlDoc=parseXML(v);

          ?

          ???????? var x;

          ???????? if(isIE)

          ?????????????????? x=''

          ???????? else

          ?????????????????? x='';

          ???????? x+='';

          ???????? if(isIE) {

          ?????????????????? x+=''+action+'('+value+',"'+mask+'"';

          ?????????????????? if(param)x+=','+param;

          ?????????????????? x+=')';

          ???????? }

          ???????? else

          ?????????????????? x+='';

          ?

          ???????? x+='';

          ???????? xslDoc=parseXML(x);

          ???????? var s;

          ???????? if(isIE)

          ???????? ?s= xmlDoc.transformNode(xslDoc)

          ???????? else{

          ?????????????????? //for mozilla/netscape

          ??????? var processor = new XSLTProcessor();

          ?????????????????? processor.importStylesheet(xslDoc);

          ?????????????????? var result = processor.transformToFragment(xmlDoc, xmlDoc);

          ??????? var xmls = new XMLSerializer();

          ??????? s = xmls.serializeToString(result);

          ???????? }

          ???????? return s;

          }

          看來他們對 xsl 用得可真是出神入化了,居然這樣就可以實現很通用的格式化轉換了,當然不客氣了,直接加到我的函數庫中哈。

          ???????? 這個代碼偶沒有看得很懂,不過確實很管用,請對 XSL 精通的朋友分析下也好讓我們學習下。

          posted @ 2007-01-05 09:22 第七日 閱讀(975) | 評論 (1)編輯 收藏

          僅列出標題  
          主站蜘蛛池模板: 黄平县| 梁河县| 西青区| 融水| 崇文区| 仙桃市| 六枝特区| 阜南县| 雷波县| 古交市| 平果县| 广西| 繁峙县| 龙岩市| 禹州市| 湘潭市| 崇文区| 杂多县| 吉林省| 正镶白旗| 集安市| 吉林市| 横山县| 德阳市| 惠东县| 垣曲县| 新源县| 荥阳市| 开原市| 涞源县| 隆安县| 承德县| 铜陵市| 虹口区| 大埔区| 聂拉木县| 枞阳县| 凤凰县| 广昌县| 海盐县| 赞皇县|