`
xyheqhd888
  • 浏览: 403695 次
  • 性别: Icon_minigender_1
  • 来自: 秦皇岛
社区版块
存档分类
最新评论

Annotion

阅读更多

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

2. 限定Override父类方法@Override

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

   如下例:

package ysu.hxy;

public class CustomClass
{
	@Override
	public String ToString()
	{
		return "customObject";
	}
}

 

编译时会报告错误:

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标示的方法,编译器必须提出警告信息。

package ysu.hxy;

public class Something
{
     //使用@Deprecated 为getSomething()方法加上标示
     @Deprecated public Something getSomething()
     {
           return new Something();
     }
}

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

package ysu.hxy;

public class SomethingDemo 
{
	public static void main(String[] args) 
	{
		Something some = new Something();
		//调用被@Deprecated标示的方法
		some.getSomething();
	}
}

 编译时会出现以下警告:

             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类型之一,它对编译器说明某个方法中若有警告信息,则加以抑制,不用在编译完成后出现警告。使用方式参见下面简单示例:

package ysu.hxy;

import java.util.*;

public class SomeClass2
{
   @SuppressWarnings(value=("unchecked"))
   public void doSomething()
    {
        Map map = new HashMap();
        map.put("some","thing");
    }
}

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

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

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

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

5.  自定义Annotation类型:

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

package ysu.hxy;

public @interface Debug{}

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

public class SomeObject
{
   @Debug
   public void doSomething()
   {
       //...
   }
}

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

 

package ysu.hxy;

public @interface UnitTest
{
  String value();
}

 

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

public class MathTool
{
   @UnitTest("GCD");
   public static int gcdOf(int num1,int num2)
   {
      //...
   }
}

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

package ysu.hxy;

public @interface FunctionTest
{
  String[] value();
}

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

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

package ysu.hxy;

public @interface UnitTest2
{
   String value() default "noMethod";
}

 

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

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

package ysu.hxy;

public @interface Process
{
   public enum Current  {NONE,REQUIRE,ANALYSIS,DESIGN,SYSTEM};

   Current current() default  Current.NONE;
   String tester();
   boolean ok();
}

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

package ysu.hxy;

public class Application
{
   @Process
   (
       current = Process.Current.ANALYSIS,
       tester = "Justin Lin",
       ok = true
   )
   public void doSomething()
  {
     //....
  }
}

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

 

import ysu.hxy.Debug;
public class Test
{
   @Debug
   public void doTest()
   {
   }
}

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

public class Test
{
    @ysu.hxy.Debug
    public void doTest()
    {
    }
}

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics