`
gladto
  • 浏览: 80763 次
  • 性别: Icon_minigender_1
  • 来自: 青岛
社区版块
存档分类
最新评论

[转]@SuppressWarnings 详解

    博客分类:
  • Java
阅读更多

背景知识:
       从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. }  
public class OverrideDemo {
    @Override
public String tostring() {
        return super.toString();
    }
}



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

引用
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. }  
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是为了生成文档的需要,例如:

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



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. }  
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类型声明以及

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

import java.lang.annotation.*;
/**
* 使用annotation来描述那些被标注的成员是不稳定的,需要更改
*/
public @interface Unstable {
}




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

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



以下的例子更加复杂。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. }  
/**
* 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类型将一个数组作为了唯一的成员。数组中的每个元素都是异常类。为了加强对未检查的异常(此类异常都是在运行时抛出)进行报告,我们可以在代码中对异常的类型进行限制:

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




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.   }  
  @Target(ElementType.METHOD)
    public @interface MyAnnotation {
        ... 
    }




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


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

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


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



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

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

                                                         [本编完]

分享到:
评论

相关推荐

    关于@SuppressWarnings("uncheck ")(转)

    ### 关于@SuppressWarnings("unchecked")详解 在Java编程中,`@SuppressWarnings` 是一个非常有用的注解,它允许开发者暂时忽略某些编译警告。这在处理一些已知但并不影响程序运行安全性的警告时非常有用。本文将...

    @SuppressWarnings

    ### @SuppressWarnings 注解详解 #### 一、概述 在Java编程中,`@SuppressWarnings`是一个十分重要的注解,主要用于抑制代码中的警告信息。随着Java语言的发展,为了提高代码质量和安全性,J2SE 5.0引入了许多新...

    java中的SuppressWarnings(xxx).doc

    ### Java中的@SuppressWarnings详解 #### 一、@SuppressWarnings("serial")的理解与应用 ##### 1.1 注解概述 `@SuppressWarnings("serial")` 是 Java 中一个重要的注解,用于抑制有关 `serialVersionUID` 的编译...

    java SuppressWarnings

    ### Java SuppressWarnings详解 在Java开发过程中,经常会遇到编译器警告的问题,这些警告虽然不会阻止程序的编译和运行,但过多的警告会影响代码的可读性和维护性。为了解决这一问题,Java提供了`@...

    annotation 详解

    ### Annotation详解 #### 一、概述 在Java编程语言中,`Annotation`(注解)是一种元数据形式,用于向编译器或分析工具提供有关程序的信息,而不会影响程序的实际执行逻辑。开发者可以通过注解来标记代码的不同...

    jdk注释讲解

    ### JDK注释详解:深入理解Java中的注解 在Java开发中,注解(Annotation)是一种重要的元数据机制,用于向编译器、工具或框架提供额外的信息,从而增强代码的功能性和可读性。本文将从JDK源注释出发,深入解析三种...

    Java Annotation详解

    在代码中使用注解时,将注解放在类、方法、字段、参数等元素前,比如 `@Override` 用于标记重写父类方法,`@Deprecated` 标记已废弃的方法,`@SuppressWarnings` 抑制编译器警告。注解不仅可以用于源码,还可以存在...

    annotation详解

    【标题】:注解(Annotation)详解 注解(Annotation)是Java编程语言中的一个重要特性,自Java 5版本引入,它提供了一种安全的方法来将元数据与代码关联。元数据是关于数据的数据,可以用来提供程序的额外信息,如...

    JavaAnntation详解.doc

    ### Java Annotation 详解 #### 元数据的作用 在 Java 中,元数据(Metadata)是一种用于描述其他数据的数据。在 Java 开发中,元数据主要通过注解(Annotation)的形式来体现。注解不仅可以帮助开发者更好地理解...

    最全Java注解图文超详解(建议收藏).pdf

    `@Override` 用于标记重写父类方法,`@Deprecated` 标记不再推荐使用的代码,`@SuppressWarnings` 可以抑制编译器警告。 2. **元注解**:元注解是用于定义其他注解的注解,包括 `@Retention`(定义注解的生命周期)...

    Java 注解技术视频详解

    Java提供了三种预定义的元注解,它们分别是`@Override`、`@Deprecated`和`@ SuppressWarnings`。`@Override`用于标记重写父类方法的方法,确保编译器检查方法是否真正覆盖了父类方法;`@Deprecated`用于标记不再推荐...

    Java Annonation

    ### Java Annotation 规范详解 #### 一、Java Annotation 概述 在现代软件开发过程中,元数据(Metadata)的概念变得越来越重要。元数据是指关于数据的数据,它可以帮助我们更好地理解、管理和处理程序中的信息。...

    最全Java注解图文超详解(建议收藏)

    以下是对Java注解的全面详解: 1. **注解类型**: Java注解有三种类型:源码级注解、编译器注解和运行时注解。源码级注解在编译后不会保留,仅用于编译器进行语法检查;编译器注解会影响编译过程,如`@Override`;...

    java或Java框架中常用的注解及其作用详解_资料.docx

    - `@ SuppressWarnings`:此注解用于指示编译器忽略特定类型的警告,如在使用过时方法时产生的"deprecation"警告。 2. **Java第三方注解** - 在Spring框架中,注解被广泛使用以简化配置和增强代码的可读性: - `...

    Java 基础(5-8) - 注解机制详解.pdf

    Java基础(5-8) - 注解机制详解 Java中的注解机制是从JDK1.5版本开始引入的特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。它主要的作用有四方面:生成文档、编译检查、编译时...

    Java软件开发实战 Java基础与案例开发详解 16-2 JDK内置的基本标注类型 共14页.pdf

    本篇文章将重点介绍第16章中的内容——JDK内置的基本标注类型,包括`Override`、`Deprecated`、以及`SuppressWarnings`这三个核心标注。 ### 16.2 JDK内置的基本标注类型 #### 16.2.1 重写(Override) **概述**...

    Android Webview添加网页加载进度条实例详解

    推荐阅读:Android WebView线性进度条实例详解 最近在android项目中使用webview嵌套了一个抽奖活动网页,活动上线,运行良好(改了N次需求和突发bug),还好这种模式的活动,只需要修改网页,不需要重新打包发布市场...

    JavaSE071Target及ElementType详解.docx

    JavaSE071Target及ElementType详解 JavaSE071Target及ElementType是Java语言中两个重要的概念,它们都是Java注解(Annotation)的组成部分。本文将详细介绍JavaSE071Target及ElementType的概念、用法和实现原理。 ...

Global site tag (gtag.js) - Google Analytics