Java Annotion

来源:互联网 发布:淘宝网冬季阔腿裙裤 编辑:程序博客网 时间:2024/05/24 04:57

1. Annotation对程序运行没有影响,它的目的在于对编译器或分析工具说明程序的某些信息,您可以在包、类、方法、域成员等加上Annotation。每个Annotation对应于一个实际的Annotation类型。

2. 限定Override父类方法@Override

    java.lang.Override是J2SE 5.0中标准的Annotation类型之一,它对编译器说明某个方法必须是重写父类中的方法。编译器得知这项信息后,在编译程序时如果发现被@Override标示的方法并非重写父类中的方法,就会报告错误。

   如下例:

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public class CustomClass  
  4. {  
  5.     @Override  
  6.     public String ToString()  
  7.     {  
  8.         return "customObject";  
  9.     }  
  10. }  

 

编译时会报告错误:

D:/Java_Test>javac -d . CustomClass.java
CustomClass.java:5: 方法未覆盖其父类的方法
        @Override
         ^
1 错误

 

这就是java.lang.Override这个Annotation类型的作用。如果这里不没有@Override,则此类编译时并不会出现任何的错误,编译器不会知道是想重写toString()方法,只会以为是定义了一新的ToString()方法。将此倒中ToString()方法改为toString()方法编译时就不用有问题了。

2. java.lang.Override是一个Marker Annotation,就是用于标示的Annotation。Annotation类型与Annotation实际上是有区分的,Annotation是否Annotation类型的实例。例如@Override是个Annotation,它是java.lang.Override类型的一个实例,一个文件中可以有很多个@override,但它们都是属于java.lang.Override类型。

3. 标示方法为Deprecated @Deprecated:

    java.lang.Deprecated是J2SE5.0中标准的Annotation类型之一,它对编译器说明某个方法已经不建议使用。如果有开发人员试图使用或者重写被@Deprecated标示的方法,编译器必须提出警告信息。

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public class Something  
  4. {  
  5.      //使用@Deprecated 为getSomething()方法加上标示  
  6.      @Deprecated public Something getSomething()  
  7.      {  
  8.            return new Something();  
  9.      }  
  10. }  

 如果有人试图在继承这个类后重写或者在程序中调用getSomething()方法,则编译时会有警告出现。如下所示:

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public class SomethingDemo   
  4. {  
  5.     public static void main(String[] args)   
  6.     {  
  7.         Something some = new Something();  
  8.         //调用被@Deprecated标示的方法  
  9.         some.getSomething();  
  10.     }  
  11. }  

 编译时会出现以下警告:

             D:/Java_Test>javac -d . SomethingDemo.java
              注意:SomethingDemo.java 使用或覆盖了已过时的 API。
              注意:要了解详细信息,请使用 -Xlint:deprecation 重新编译。

  java.lang.Deprecated也是一个Marker Annotation,简单地说就是用于标示。

4. 抑制编译器警告@SuppressWarnings

    java.lang.SuppressWarnings是J2SE5.0中标准的Annotations类型之一,它对编译器说明某个方法中若有警告信息,则加以抑制,不用在编译完成后出现警告。使用方式参见下面简单示例:

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. import java.util.*;  
  4.   
  5. public class SomeClass2  
  6. {  
  7.    @SuppressWarnings(value=("unchecked"))  
  8.    public void doSomething()  
  9.     {  
  10.         Map map = new HashMap();  
  11.         map.put("some","thing");  
  12.     }  
  13. }  

 理论上是可以抑制警告的,你也可以指定忽略多个警告:如

@SuppressWarnings(value={"unchecked","deprecation"});

不过在JDK 5.0上并没有实现这个Annotation的功能,所以@SuppressWarnings实际上并没有作用。如果真要关掉警告,那么在编译时加上-nowarn是另一个方法,只不过这会关掉所有的警告信息。

@SuppressWarnings是所谓的Single-Value Annotation,因为这样的Annotation只有一个成员,称为value成员,可在使用Annotation时作额外的信息指定。

5.  自定义Annotation类型:

     要定义一个Annotation所需的动作,就类似于定义一个接口,只不过使用的是@interface,如下范例:

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public @interface Debug{}  

 由于是一个Marker Annotation,所以没有任何成员在Annotation定义中。编译完成后就可以在程序代码中使用这个Annotation。例如:

Java代码  收藏代码
  1. public class SomeObject  
  2. {  
  3.    @Debug  
  4.    public void doSomething()  
  5.    {  
  6.        //...  
  7.    }  
  8. }  

 稍后将看到如何在程序中获得Annotation信息,接着来看看如何定义一个Single-Annotation,它只有一个value成员,如下:

 

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public @interface UnitTest  
  4. {  
  5.   String value();  
  6. }  

 

实际上定义了value()方法,编译器在编译时会自动产生一个value的域成员,接着在使用UnitTest Annotation时要指定值,如:

Java代码  收藏代码
  1. public class MathTool  
  2. {  
  3.    @UnitTest("GCD");  
  4.    public static int gcdOf(int num1,int num2)  
  5.    {  
  6.       //...  
  7.    }  
  8. }  

  @UnitTest("GCD")实际上是 @UnitTest(value="GCD")的简便写法,value也可以是数组值。例如定义一个FunctionTest的Annotation类型。

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public @interface FunctionTest  
  4. {  
  5.   String[] value();  
  6. }  

 在使用此段代码定义的Annotation时,可以写成@Functiontest({"method1","method2"})这样的简便形式,或是

@Functiontest(value={"method1","method2"}) 这样的详细形式,也可以对value成员设定默认值,使用default关键词即可。

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public @interface UnitTest2  
  4. {  
  5.    String value() default "noMethod";  
  6. }  

 

这样如果使用@UnitTest2时没有指定value值,则value默认就是noMethod。

  也可以为Annotation定义额外的成员,以提供额外的信息给分析工具。如下例定义使用枚举类型、String与booean类型来定义Annotation的成员。

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public @interface Process  
  4. {  
  5.    public enum Current  {NONE,REQUIRE,ANALYSIS,DESIGN,SYSTEM};  
  6.   
  7.    Current current() default  Current.NONE;  
  8.    String tester();  
  9.    boolean ok();  
  10. }  

 可以用如下的代码来使用这个范例定义Annotation的成员。

Java代码  收藏代码
  1. package ysu.hxy;  
  2.   
  3. public class Application  
  4. {  
  5.    @Process  
  6.    (  
  7.        current = Process.Current.ANALYSIS,  
  8.        tester = "Justin Lin",  
  9.        ok = true  
  10.    )  
  11.    public void doSomething()  
  12.   {  
  13.      //....  
  14.   }  
  15. }  

 当使用@interface自行定义Annotation类型时,实际上是自动继承了java.lang.annotation.Annotation接口,并由编译器自动完成其他产生的细节,并且在定义Annotation类型时,不能继承其他的Annotation类型或接口。定义Annotation类型时也可以使用包机制来管理类,如果在别的包下使用自定义的Annotation,记得使用import告诉编译器类型的包位置。例如:

 

Java代码  收藏代码
  1. import ysu.hxy.Debug;  
  2. public class Test  
  3. {  
  4.    @Debug  
  5.    public void doTest()  
  6.    {  
  7.    }  
  8. }  

或是使用完整的Annotation名称, 例如:

Java代码  收藏代码
  1. public class Test  
  2. {  
  3.     @ysu.hxy.Debug  
  4.     public void doTest()  
  5.     {  
  6.     }  

原创粉丝点击