zoukankan      html  css  js  c++  java
  • 转]@SuppressWarnings 详解

    转自:http://gladto.iteye.com/blog/728634

    背景知识: 
           从JDK5开始提供名为Annotation(注释)的功能,它被定义为JSR-175规范。注释是以“@注释名”在代码中存在的,还可以添加一些参数值,例如:@SuppressWarnings(value="unchecked")。注释可以附加在package, class, method, field等上面,相当于给它们添加了额外的辅助信息,我们可以通过反射机制编程实现对这些元数据的访问。如果没有外部解析工具等对其加以解析和处理的情况,本身不会对Java的源代码或class文件等产生任何影响,也不会对它们的执行产生任何影响。 
         元数据的作用,大致可分为三种:编写文档,通过代码里标识的元数据生成文档;代码分析,通过代码里标识的元数据对代码进行分析;编译检查,通过代码里标识的元数据让编译器能实现基本的编译检查。 

    JDK5内置的基本注释 
        JDK5内置了一些常用的注释,可以在编译时帮我们捕获部分编译错误,及提示信息,下面介绍下这些注释的用法: 

    1、@Override定义在java.lang.Override中,此注释只适用于修辞方法,表示一个方法声明打算重写超类中的另一个方法声明。如果方法利用此注释类型进行注解但没有重写超类方法,则编译器会生成一条错误消息。例如我们为某类重写toString()方法却写成了tostring(),并且我们为该方法添加了@Override注释;代码如下: 

    Java代码 复制代码
    1. public class OverrideDemo {   
    2.     @Override  
    3. public String tostring() {   
    4.         return super.toString();   
    5.     }   
    6. }  
    Java代码  收藏代码
    1. public class OverrideDemo {  
    2.     @Override  
    3. public String tostring() {  
    4.         return super.toString();  
    5.     }  
    6. }  



    在编译时,会提示以下错误信息: 

    引用
    OverrideTest.java:4: 方法未覆盖其父类的方法 
            @Override 
             ^1 错误



    2、@Deprecated定义在java.lang.Deprecated中,此注释可用于修辞方法、属性、类,表示不鼓励程序员使用这样的元素,通常是因为它很危险或存在更好的选择。在使用不被赞成的程序元素或在不被赞成的代码中执行重写时,编译器会发出警告。使用@Deprecated的示例代码如下:

    Java代码 复制代码
    1. public class DeprecatedDemo {   
    2.     public static void main(String[] args) {   
    3.          DeprecatedClass.DeprecatedMethod();   
    4.     }   
    5. }   
    6.   
    7. class DeprecatedClass {   
    8.     @Deprecated  
    9.     public static void DeprecatedMethod() {   
    10.         // TODO   
    11.     }   
    12. }  
    Java代码  收藏代码
    1. public class DeprecatedDemo {  
    2.     public static void main(String[] args) {  
    3.          DeprecatedClass.DeprecatedMethod();  
    4.     }  
    5. }  
    6.   
    7. class DeprecatedClass {  
    8.     @Deprecated  
    9.     public static void DeprecatedMethod() {  
    10.         // TODO  
    11.     }  
    12. }  



    在编译时,会得到以下提示信息: 

    引用
    注意:DeprecatedDemo.java 使用或覆盖了已过时的 API。 
    注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。



    如果在编译时添加-Xlint:deprecation参数,我们能更清楚的看到该警告的详细信息,如下: 

    引用
    DeprecatedDemo.java:6: 警告:[deprecation] SomeClass 中的 DeprecatedMethod() 已过时 
                    SomeClass.DeprecatedMethod(); 
                             ^1 警告


    要注意@Deprecated与@deprecated的区别,@deprecated是为了生成文档的需要,例如:

    Java代码 复制代码
    1. class DeprecatedClass {   
    2.         /**  
    3. * @deprecated  此方法已过时,不建议使用  
    4. */  
    5. @Deprecated  
    6.     public static void DeprecatedMethod() {   
    7.         // TODO   
    8.     }   
    9. }  
    Java代码  收藏代码
    1. class DeprecatedClass {  
    2.         /** 
    3. * @deprecated  此方法已过时,不建议使用 
    4. */  
    5. @Deprecated  
    6.     public static void DeprecatedMethod() {  
    7.         // TODO  
    8.     }  
    9. }  



    3、@SuppressWarnings定义在java.lang.SuppressWarnings中,用来抑制编译时的警告信息。与前两个注释有所不同,你需要添加一个参数才能正确使用,这些参数值都是已经定义好了的,我们选择性的使用就好了,参数如下: 


    通过上面的表格,你应该了解到每个参数的用意了,下面我就以一个常用的参数unchecked为例,为你展示如何使用@SuppressWarnings注释,示例代码如下:

    Java代码 复制代码
    1. import java.util.List;   
    2. import java.util.ArrayList;   
    3. public class SuppressWarningsDemo {   
    4.         public static List cache = new ArrayList();   
    5.         //@SuppressWarnings(value = "unchecked")   
    6.         public void add(String data) {   
    7.             cache.add(data);   
    8.         }   
    9. }  
    Java代码  收藏代码
    1. import java.util.List;  
    2. import java.util.ArrayList;  
    3. public class SuppressWarningsDemo {  
    4.         public static List cache = new ArrayList();  
    5.         //@SuppressWarnings(value = "unchecked")  
    6.         public void add(String data) {  
    7.             cache.add(data);  
    8.         }  
    9. }  


    当我们不使用@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类型声明以及

    Java代码 复制代码
    1. @interface与interface之间的不同:    
    2.   
    3. import java.lang.annotation.*;   
    4. /**  
    5. * 使用annotation来描述那些被标注的成员是不稳定的,需要更改  
    6. */  
    7. public @interface Unstable {   
    8. }  
    Java代码  收藏代码
    1. @interface与interface之间的不同:   
    2.   
    3. import java.lang.annotation.*;  
    4. /** 
    5. * 使用annotation来描述那些被标注的成员是不稳定的,需要更改 
    6. */  
    7. public @interface Unstable {  
    8. }  




    下面的另一个例子只定义了一个成员。并通过将这个成员命名为value,使我们可以方便的使用这种annotation的快捷声明方式: 

    Java代码 复制代码
    1. /**  
    2. * 使用Author这个annotation定义在程序中指出代码的作者  
    3. */  
    4. public @interface Author {   
    5.       /** 返回作者名 */  
    6.       String value();   
    7. }  
    Java代码  收藏代码
    1. /** 
    2. * 使用Author这个annotation定义在程序中指出代码的作者 
    3. */  
    4. public @interface Author {  
    5.       /** 返回作者名 */  
    6.       String value();  
    7. }  



    以下的例子更加复杂。Reviews annotation类型只有一个成员,但是这个成员的类型是复杂的:由Review annotation组成的数组。Review annotation类型有3个成员:枚举类型成员grade、表示Review名称的字符串类型成员Reviewer、具有默认值的字符串类型成员 Comment。

    Java代码 复制代码
    1. /**  
    2. * Reviews annotation类型只有一个成员,  
    3. * 但是这个成员的类型是复杂的:由Review annotation组成的数组  
    4. */  
    5. @Retention(RetentionPolicy.RUNTIME)   
    6. public @interface Reviews {   
    7.     Review[] value();   
    8. }   
    9. /**  
    10. * Review annotation类型有3个成员:   
    11. * 枚举类型成员grade、  
    12. * 表示Review名称的字符串类型成员Reviewer、  
    13. * 具有默认值的字符串类型成员Comment。  
    14. */  
    15. public @interface Review {   
    16.     // 内嵌的枚举类型   
    17.      public static enum Grade { EXCELLENT, SATISFACTORY, UNSATISFACTORY };   
    18.      // 下面的方法定义了annotation的成员   
    19.      Grade grade();   
    20.      String reviewer();   
    21.      String comment() default "";   
    22. }  
    Java代码  收藏代码
    1. /** 
    2. * Reviews annotation类型只有一个成员, 
    3. * 但是这个成员的类型是复杂的:由Review annotation组成的数组 
    4. */  
    5. @Retention(RetentionPolicy.RUNTIME)  
    6. public @interface Reviews {  
    7.     Review[] value();  
    8. }  
    9. /** 
    10. * Review annotation类型有3个成员:  
    11. * 枚举类型成员grade、 
    12. * 表示Review名称的字符串类型成员Reviewer、 
    13. * 具有默认值的字符串类型成员Comment。 
    14. */  
    15. public @interface Review {  
    16.     // 内嵌的枚举类型  
    17.      public static enum Grade { EXCELLENT, SATISFACTORY, UNSATISFACTORY };  
    18.      // 下面的方法定义了annotation的成员  
    19.      Grade grade();  
    20.      String reviewer();  
    21.      String comment() default "";  
    22. }  




    最后,我们来定义一个annotation方法用于罗列出类运行中所有的unchecked异常。这个 annotation类型将一个数组作为了唯一的成员。数组中的每个元素都是异常类。为了加强对未检查的异常(此类异常都是在运行时抛出)进行报告,我们可以在代码中对异常的类型进行限制: 

    Java代码 复制代码
    1. public @interface UncheckedExceptions {    
    2.      Class[] value();   
    3. }  
    Java代码  收藏代码
    1. public @interface UncheckedExceptions {   
    2.      Class[] value();  
    3. }  




    Meta-Annotation类型: 

    Annotation 类型可以被它们自己所标注。Java5.0定义了4个标准的meta-annotation类型,分别是:Target、Retention、Documented、Inherited,它们被用来提供对其它annotation类型作说明。 这些类型和它们所支持的类在java.lang.annotation包中可以找到。 

    @Target的用法:指示注释类型所适用的程序元素的种类。如果注释类型声明中不存在 Target 元注释,则声明的类型可以用在任一程序元素上。如果存在这样的元注释,则编译器强制实施指定的使用限制。 例如,以下这个注释只能用来声明方法: 

    Java代码 复制代码
    1. @Target(ElementType.METHOD)   
    2.   public @interface MyAnnotation {   
    3.       ...    
    4.   }  
    Java代码  收藏代码
    1. @Target(ElementType.METHOD)  
    2.   public @interface MyAnnotation {  
    3.       ...   
    4.   }  




    java.lang.annotation.ElementType是一个枚举类型,它具有以下定义: 


    @Retention的用法:指示注释类型的注释要保留多久。如果注释类型声明中不存在 Retention 注释,则保留策略默认为 RetentionPolicy.CLASS,例如: 

    Java代码 复制代码
    1. @ Retention(RetentionPolicy.CLASS)   
    2.     public @interface MyAnnotation {   
    3.         ...    
    4.     }  
    Java代码  收藏代码
    1. @ Retention(RetentionPolicy.CLASS)  
    2.     public @interface MyAnnotation {  
    3.         ...   
    4.     }  


    java.lang.annotation.RetentionPolicy是一个枚举类型,它具有以下定义: 



    @Documented的用法:指示某一类型的注释将通过 javadoc 和类似的默认工具进行文档化。应使用此类型来注释这些类型的声明:其注释会影响由其客户端注释的元素的使用。如果类型声明是用 Documented 来注释的,则其注释将成为注释元素的公共 API 的一部分。Documented是一个没有成员的注释。 

    @Inherited的用法:指示注释类型自动被子类继承。 Inherited也是一个没有成员的注释。 
    注意,如果使用@Inherited注释类以外的任何事物都是无效的。还要注意,此元注释仅对从超类继承注释有效;对已实现接口的注释无效。 

  • 相关阅读:
    Silverlight 4中把DataGrid数据导出Excel
    C#正则的委托和lambda表达式用法
    C#简单的写日志方法
    GAE上传失败
    asp.net后台进程做定时任务
    ASP.NET页面生命周期描述
    巴士电台新版发布
    jQuery 1.51.7一些值得注意的更新
    wxPython应用心得
    Ajax保留浏览器历史的两种解决方案(Hash&Pjax)[转]
  • 原文地址:https://www.cnblogs.com/laobiao/p/5605440.html
Copyright © 2011-2022 走看看