Java中的注解剖析

在Java当中设定了许多"注解",不仅能够使程序更加容易理解,而且能够对特定的程序段进行检查

增强程序的安全性,在java当中有 内置的注解 和 自定义的注解 两种,下面进行介绍

一、内置的注解

1、内置的注解有三种,都是java语言内部已经定义好的注解,用于实现部分功能

   分别是:@Override(继承)、@Deprecated(不赞成)、@SuppressWarnings(禁止警告)

   他们所在的类分别是 java.lang.Override/java.lang.Deprecated/java.lang.SupressWarnings

   @Override:表示当前注解的方法将重写父类当中的对应的方法,如果不符合重写的规则,那么

              程序在编译时就会报错

   @Deprecated:该注解用在那些已经废弃了的(即在以后不打算在用的)类或方法前面,如果

                某个方法或类已经被该标签注解过了,那么如果接下来程序中又用到了该方法

                或者类的话,那么程序就会有产生警告       @SuppressWarnings:关闭指定的编译警告信息,即强制编译器不发出警告

   其中前两个标签都是没有参数的,只要将对应的标签写在相应的程序元素的前面就行了,

   一般所有的注解都写在程序元素的前面,而且要单独一行

   如:

        @Override

        public boolean equals(Object obj){.....}

2、当程序当中有许多的不可避免的警告时,那么在输出窗口当中就会出现非常多的警告文字,使得

   程序变的臃肿,那么这时@SuppressWarnings就派上用场了,将@SuppressWarnings写在想要屏蔽、

   警告的程序元素的前面就能够将警告屏蔽,该标签能够用于类和方法,如果用在类的前面的话

   那么意味着类中的所有的成员都将被施加该注解,所以,建议将该标签尽量的用在恰当的范围内

   该方法应有String[]类型的参数,这些参数指定了到底屏蔽那些类型的警告,形式如下:

    ① 当只有一个参数时,可以使用下面的两种形式:

       @SuppressWarnings(value={"unchecked"})

       @SuppressWarnings ("unchecked")

    ②当具有多个参数时,那么形式为:

       @SuppressWarnings ({"unchecked","deprection"})

       至于参数具体是什么可以根据程序中出现的警告语句来确定,

       比如在没有加入该标签时出现了警告,我们会发现该语句开头当中有该警告的英文参数

       如:warning : [deprection] StringBuffer InputStream in java.io has been deprecated

        那么这个[deprection]就是噶出警告的英文参数,所以确定参数并不是问题

二、自定义注解

    自定义注解就是说可以自己定义注解,一般来说自己定义的注解只是用来使程序更加易读,只是提供一        些信息,自定义注解分成三类:没有任何元素的注解、只有一个元素的注解、有多个元素的注解

    自定义的注解的形式实际就是在interface前面加上一个标示符@,自定义的注解和内置的注解使用方法

    是一样的,都是使用在程序元素前面,单独成一行

    还有一点需要注意的是自定义的注解和声明一个接口/类相似,也有访问权限修饰符

    自定义的注解自动继承 java.lang.annotation.Annotation接口

    ①没有任何元素的注解:

      public @interface WorkInProgress{ }

          @WorkInProgress

     public static float computeTax()

     {return 0.0 ;}

     没有任何元素的注解只能通过名字祈祷一种标示作用,不能显示其他的信息

     如,上述的注解用在该方法前面,通过名字WorkInprogress可以提示说computeTax方法还没有

     写完

    ②单值注解

      public @interface Task

      {           String value();

      }

      使用方式如: @Task("Implement tax computations")

      注意单值注解的声明的内部一般都用value这个名字,如果用其他的名字,则在使用该注解时

      必须明确指出这个名字 如:

      public @interface Task

      {            String description();          }

      使用方法如:@Task(description="Implement tax computations")

     ③多值注解

       public @interface Task

       {             String description();

            String targetDate();

            int esimateHours();

            String addtionalNote();         }

      使用方法:@Task(description="Implement tax computations",

                       targetDate="Jan 1 , 2014",

                       esimateHours=50,

                       addtionalNote="Implement" )

       不论是单值还是多指都只是通过那些名字和 = 后面的参数来提供一些信息,别无其他

       值得注意的是:          ①java允许为注解的成员指定默认值,同过default关键字完成,

         比如,若为上面的成员 String description()指定默认值,就将之写成:

             String description() defualt "Implement tax computations" ;

         在使用标签时不给该成员赋值,那么,就是用该默认的值           ② 创建自定义注解时应遵守规则:

          为了创建注解参数,就必须声明不包含任何参数的方法

          方法不能包含任何throws,extends的子句

          方法的返回值应该为:基本类型、String、类、枚举 等

三、我们还可以为注解添加注解,这样的注解称为元注解

    java目前定义了4种元注解:

       @Target

       @Retention          @Documented

       @Inherited

这四种注解元枚举变量都位于java.lang.annotation包当中,所以在使用这四种元注解前

必须添加语句:

import java.lang.anntation.Annotation;

1、@Target该标签用于指定一个注解可以用于哪些程序元素,通过实例会非常容易理解其用法:

     如:

        @Target(ElementType.METHOD)

        public @interface Bbp

        {  ....... }

     程序当中为Bbp注解添加了注解@Target(ElementType.METHOD),其中的METHOD就限定了

     Bbp注解只能用于方法,即只能注解方法,否则会报错;ElementType还有很多类型用来规定

     注解可用的不同的位置:

     ElementType.FIELD:可以用于字段(字段的范围很宽泛)

     ElementType.METHOD:可以用于方法

     ElementType.PACKAGE:可以用于包

     ElementType.TYPE:可以用于 类、接口、enum、           ElementType.LOCAL_VARIABLE:可以用于局部变量   2、@Retention:由于该元注解有很多的注意事项,所以我们将该元注解单独的记录在一个.doc文件当中

               见该doc文档

3、@Documented:

   当一个注解被@Documented注解时,就意味着当使用javadoc工具生成源代码的HTML格式的API文档时,

   这个注解是能看见的,如:

package rog.myPackage ;

import java.lang.annotation.Annotation;

@Documented @interface WorkInProgress{}

@Documented @interface Task {    String str();

   int value(); }

public class Hellow

{    @WorkInProgress

   @Task(str="you are right",value=10)

   public static void main(String[]args)    {        return;       } }

假设该文件为Hellow.java 文件的话,那么如果使用javadoc工具时:

  javadoc Hellow.java

在生成的index.html文档中,会有这样的文字:

“方法的具体解释为    main

@WorkInProgress

   @Task(str="you are right",value=10)

   public static void main(String[]args)”

可见将@workInprogress 和 @Task 的内容都保存到了文档当中,这解释main方法提供了详细的解释

而在源文件当中使用//或/**....*/是不会在index.html文档中留下任何痕迹的

4、@Inherited

   如果某个注解标记了某个类的话,同时这个注解又使用了这个元注解的话,那么当某个子类

   继承这个父类时,标记父类的注解就同时被子类继承了,这是非常有用的,

   比如说,某个父类还没有被完成,这是我们用一个@NoFinished对值进行注解,如果某个子类

   继承了这个父类的话,因为父类没有完成,那么子类就没有完成,这样我们对@NoFinish使用

   @Inherited元注解,那么子类自然就继承了这个@NoFinished注解,在实际中由于程序非常的

   长,那么,使用这个元注解对于程序的校检是非常有帮助的

 

posted @ 2014-08-10 14:10  RoperLee  阅读(243)  评论(0)    收藏  举报