转:J2SE5中的最新注释功能SuppressWarnings
| 一、什么是注釋 ??? 說起注釋,得先提一提什么是元數(shù)據(jù)(metadata)。所謂元數(shù)據(jù)就是數(shù)據(jù)的數(shù)據(jù)。也就是說,元數(shù)據(jù)是描述數(shù)據(jù)的。就象數(shù)據(jù)表中的字段一樣,每個字段描述了這個字段下的數(shù)據(jù)的含義。而J2SE5.0中提供的注釋就是java源代碼的元數(shù)據(jù),也就是說注釋是描述java源代碼的。在J2SE5.0中可以自定義注釋。使用時在@后面跟注釋的名字。 ???????????????????????????????????????????????????????????????????????????????????? 二、J2SE5.0中預(yù)定義的注釋 ??? 在J2SE5.0的java.lang包中預(yù)定義了三個注釋。它們是Override、Deprecated和SuppressWarnings。下面分別解釋它們的含義。 Override ??? 這個注釋的作用是標(biāo)識某一個方法是否覆蓋了它的父類的方法。那么為什么要標(biāo)識呢?讓我們來看看如果不用Override標(biāo)識會發(fā)生什么事情。 | |
| 假設(shè)有兩個類Class1和ParentClass1,用Class1中的myMethod1方法覆蓋ParentClass1中的myMethod1方法。 class ParentClass1 ...{ public void myMethod1() ...{...} } class Class1 extends ParentClass1 ...{ public void myMethod2() ...{...} } 建立Class1的實例,并且調(diào)用myMethod1方法 ParentClass1 c1 = new Class1(); c1.myMethod1(); 以上的代碼可以正常編譯通過和運行。但是在寫Class1的代碼時,誤將myMethod1寫成了myMethod2,然而在調(diào)用時,myMethod1并未被覆蓋。因此,c1.myMethod1()調(diào)用的還是ParentClass1的myMethod1方法。更不幸的是,程序員并未意識到這一點。因此,這可能會產(chǎn)生bug。 ?? 如果我們使用Override來修飾Class1中的myMethod1方法,當(dāng)myMethod1被誤寫成別的方法時,編譯器就會報錯。因此,就可以避免這類錯誤。 class Class1 extends ParentClass1 ...{ ?@Override // 編譯器產(chǎn)生一個錯誤 public void myMethod2() ...{...} } 以上代碼編譯不能通過,被Override注釋的方法必須在父類中存在同樣的方法程序才能編譯通過。也就是說只有下面的代碼才能正確編譯。 class Class1 extends ParentClass1 ...{ @Override public void myMethod1() ...{...} } Deprecated ????這個注釋是一個標(biāo)記注釋。所謂標(biāo)記注釋,就是在源程序中加入這個標(biāo)記后,并不影響程序的編譯,但有時編譯器會顯示一些警告信息。
} class Class2 extends Class1 ...{ public void myMethod()...{} } 1 1 運行javac test.java 出現(xiàn)如下警告: ??? 注意:test.java 使用或覆蓋了已過時的 API。 ??? 注意:要了解詳細信息,請使用 -Xlint:deprecation 重新編譯 ??? 使用-Xlint:deprecation顯示更詳細的警告信息: ??? test.java:4: 警告:[deprecation] Class1 中的 myMethod() 已過時 ??? public void myMethod() ??? ^ ??? 1 警告 ??? 這些警告并不會影響編譯,只是提醒你一下盡量不要用myMethod方法。 ??? SuppressWarnings ??? 這個世界的事物總是成對出現(xiàn)。即然有使編譯器產(chǎn)生警告信息的,那么就有抑制編譯器產(chǎn)生警告信息的。 ??? SuppressWarnings注釋就是為了這樣一個目的而存在的。讓我們先看一看如下的代碼。 public void myMethod() ...{ List wordList = new ArrayList(); wordList.add("foo"); } 這是一個類中的方法。編譯它,將會得到如下的警告。 ??? 注意:Testannotation.java 使用了未經(jīng)檢查或不安全的操作。 ??? 注意:要了解詳細信息,請使用 -Xlint:unchecked 重新編譯。 ??? 這兩行警告信息表示List類必須使用范型才是安全的,才可以進行類型檢查。如果想不顯示這個警告信息有兩種方法。一個是將這個方法進行如下改寫: 1 public void myMethod() { ??List<String> wordList = new ArrayList<String>(); ??wordList.add("foo"); } 另外一種方法就是使用@SuppressWarnings。 @SuppressWarnings (value={"unchecked"}) public void myMethod() { ??List wordList = new ArrayList(); ??wordList.add("foo"); } 要注意的是SuppressWarnings和前兩個注釋不一樣。這個注釋有一個屬性。當(dāng)然,還可以抑制其它警告,如: @SuppressWarnings (value={"unchecked", "fallthrough"}) 三、如何自定義注釋 ??? 當(dāng)然,也可以定義有屬性的注釋。 public @interface MyAnnotation ...{ ??String value(); } 可以按如下格式使用MyAnnotation @MyAnnotation("abc") public void myMethod() ...{ } 看了上面的代碼,大家可能有一個疑問。怎么沒有使用value,而直接就寫”abc”了。那么”abc”到底傳給誰了。其實這里有一個約定。如果沒有寫屬性名的值,而這個注釋又有value屬性,就將這個值賦給value屬性,如果沒有,就出現(xiàn)編譯錯誤。 ??? 除了可以省略屬性名,還可以省略屬性值。這就是默認(rèn)值。 public @interface MyAnnotation ...{ ??public String myMethod()...{} default “xyz”; } 可以直接使用MyAnnotation @MyAnnotation // 使用默認(rèn)值xyz public void myMethod() ...{ } 也可以這樣使用 @MyAnnotation(myMethod=”abc”) public void myMethod() ...{ } ??? 如果要使用多個屬性的話。可以參考如下代碼。 public @interface MyAnnotation ...{ public enum MyEnum...{A, B, C} public MyEnum.value1() ...{} public String value2() ...{} } @MyAnnotation(value1=MyAnnotation.MyEnum.A, value2 = “xyz”) public void myMethod() ...{ } 這一節(jié)討論了如何自定義注釋。那么定義注釋有什么用呢?有什么方法對注釋進行限制呢?我們能從程序中得到注釋嗎?這些疑問都可以從下面的內(nèi)容找到答案。 1 四、如何對注釋進行注釋 ??? 這一節(jié)的題目讀起來雖然有些繞口,但它所蘊涵的知識卻對設(shè)計更強大的java程序有很大幫助。 在上一節(jié)討論了自定義注釋,由此我們可知注釋在J2SE5.0中也和類、接口一樣。是程序中的一個基本的組成部分。既然可以對類、接口進行注釋,那么當(dāng)然也可以對注釋進行注釋。 ??? 使用普通注釋對注釋進行注釋的方法和對類、接口進行注釋的方法一樣。所不同的是,J2SE5.0為注釋單獨提供了4種注釋。它們是Target、Retention、Documented和Inherited。下面就分別介紹這4種注釋。 ?? Target ?? 這個注釋理解起來非常簡單。由于target的中文意思是“目標(biāo)”,因此,我們可能已經(jīng)猜到這個注釋和某一些目標(biāo)相關(guān)。那么這些目標(biāo)是指什么呢?大家可以先看看下面的代碼。 @Target(...ElementType.METHOD) @interface MyAnnotation ...{} @MyAnnotation // 錯誤的使用 public class Class1 ...{ @MyAnnotation // 正確的使用 public void myMethod1() ...{} } ??? 以上代碼定義了一個注釋MyAnnotation和一個類Class1,并且使用MyAnnotation分別對Class1和myMethod1進行注釋。如果編譯這段代碼是無法通過的。也許有些人感到驚訝,沒錯啊!但問題就出在@Target(ElementType.METHOD)上,由于Target使用了一個枚舉類型屬性,它的值是ElementType.METHOD。這就表明MyAnnotation只能為方法注釋。而不能為其它的任何語言元素進行注釋。因此,MyAnnotation自然也不能為Class1進行注釋了。 ?? 說到這,大家可能已經(jīng)基本明白了。原來target所指的目標(biāo)就是java的語言元素。如類、接口、方法等。當(dāng)然,Target還可以對其它的語言元素進行限制,如構(gòu)造函數(shù)、字段、參數(shù)等。如只允許對方法和構(gòu)造函數(shù)進行注釋可以寫成: @Target(...{ElementType.METHOD, ElementType.CONSTRUCTOR}) @interface MyAnnotation ...{} Retention ???? 既然可以自定義注釋,當(dāng)然也可以讀取程序中的注釋(如何讀取注釋將在下一節(jié)中討論)。但是注釋只有被保存在class文件中才可以被讀出來。而Retention就是為設(shè)置注釋是否保存在class文件中而存在的。下面的代碼是Retention的詳細用法。 @Retention(RetentionPolicy.SOURCE) @interface MyAnnotation1 ...{ } @Retention(RetentionPolicy.CLASS) @interface MyAnnotation2 ...{} @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation3 ...{} ????其中第一段代碼的作用是不將注釋保存在class文件中,也就是說象“//”一樣在編譯時被過濾掉了。第二段代碼的作用是只將注釋保存在class文件中,而使用反射讀取注釋時忽略這些注釋。第三段代碼的作用是即將注釋保存在class文件中,也可以通過反射讀取注釋。 Documented ??? 這個注釋和它的名子一樣和文檔有關(guān)。在默認(rèn)的情況下在使用javadoc自動生成文檔時,注釋將被忽略掉。如果想在文檔中也包含注釋,必須使用Documented為文檔注釋。 @interface MyAnnotation...{ } @MyAnnotation class Class1 ...{ public void myMethod() ...{ } } 使用javadoc為這段代碼生成文檔時并不將@MyAnnotation包含進去。生成的文檔對Class1的描述如下: class Class1extends java.lang.Object 而如果這樣定義MyAnnotation將會出現(xiàn)另一個結(jié)果。 @Documented @interface MyAnnotation ...{} 生成的文檔: @MyAnnotation // 這行是在加上@Documented后被加上的 class Class1extends java.lang.Object Inherited ???? 繼承是java主要的特性之一。在類中的protected和public成員都將會被子類繼承,但是父類的注釋會不會被子類繼承呢?很遺憾的告訴大家,在默認(rèn)的情況下,父類的注釋并不會被子類繼承。如果要繼承,就必須加上Inherited注釋。 @Inherited @interface MyAnnotation ...{ } @MyAnnotation public class ParentClass ...{} public class ChildClass extends ParentClass ...{ } 在以上代碼中ChildClass和ParentClass一樣都已被MyAnnotation注釋了。 五、如何使用反射讀取注釋 總結(jié) | |
轉(zhuǎn)載于:https://www.cnblogs.com/liubiqu/archive/2008/06/01/1211503.html
總結(jié)
以上是生活随笔為你收集整理的转:J2SE5中的最新注释功能SuppressWarnings的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 王者荣耀积分夺宝有什么规律
- 下一篇: 刺激战场m416最佳配件是什么