Java-注释@interface的用法

@interface是用来自定义JAVA Annotation的语法,普通的开发人员可能很少用到它,但是它的功能很强大,本文将具体介绍@interface的用法!

 

一般的应用程序开发人员可能从不需要定义一个注释类型,但定义我们自己的注释类型并不复杂。注释类型的定义跟定义一个接口相似,我们需要在 interface这个关键字前面加上一个@符号,即@interface。

注释中的每一个方法定义了这个注释类型的一个元素,注释中方法的声明中一定不能包含参数,也不能抛出异;方法的返回值被限制为简单类型、StringClassemnus、注释,和这些类型的数组。方法可以有一个缺省值。这里是一个注释类型定义的例 子:

/**

  * Describes theRequest-For-Enhancement(RFE) that led

  * to the presence of the annotated APIelement.

  */

 

public @interface RequestForEnhancement {

   int id();

   String synopsis();

     String engineer() default"[unassigned]";

   String date(); default"[unimplemented]";

}

 

一旦定义好了一个注释类型,你就可以用来作注释声明。注释一中特殊的修饰符,在其他修饰符(比如public,static,或者final等) 使用地方都可以使用。按照惯例,注释应该放在其他修饰符的前面。注释的声明用@符号后面跟上这个注释类型的名字,再后面跟上括号,括号中列出这个注释中元 素/方法的key-value对。值必须是常量。这里是一个例子,使用上面定义的注释类型:

 

@RequestForEnhancement( 

   id = 2868724, 

   synopsis = "Enabletime-travel", 

   engineer = "Mr.Peabody", 

   date = "4/1/3007" 

 

  public static voidtravelThroughTime(Date destination) { ... } 

 

     没有元素/方法的注释被成为标记(marker)注释类型,例如

       /** 

  * Indicates that the specification ofthe annotated API element 

  * is preliminary and subject tochange. 

  */ 

  public @interface Preliminary {} 

 

标记注释在使用的时候,其后面的括号可以省略,例如

@Preliminary public class TimeTravel { ...} 

如果注释中仅包含一个元素,这个元素的名字应该为value,例如:

 

/** 

  * Associates a copyright notice with the annotated API element. 

  */ 

 

  public @interface Copyright { String value(); } 

 

如果元素的名字为value,使用这个注释的时候,元素的名字和等号可以省略,如:

 

@Copyright("2002 Yoyodyne PropulsionSystems") 

 

public class OscillationOverthruster { ...} 

 

为了将上面提到的东西结合在一起,我们创建了一个简单的基于注释的测试框架。首先我们需要一个标记注释类型用以说明一个方法是一个测试方法,并被测试工具执行。

 

import java.lang.annotation.*; 
 
  /** 
  * Indicates that the annotated method is a test method. 
  * This annotation should be used only on parameterless staticmethods. 
  */ 
 
  @Retention(RetentionPolicy.RUNTIME) 
 
   @Target(ElementType.METHOD) 
 
  public @interface Test { } 


 

  我们可以注意到这个注释类型本省也被注释了,这种注释叫做元注释。第一注释 (@Retention(RetentionPolicy.RUNTIME))表示这种类型的注释被VM保留从而使其能够通过反射在运行时读取;第二个注 释@Target(ElementType.METHOD)表示这种注释只能用来注释方法。

下面是一个简单的类,其中的几个方法被加了上面的注释:

 

  

 public class Foo { 
 
   @Test public static void m1() { } 
 
   public static void m2() { } 
 
   @Test public static void m3() { 
        throw newRuntimeException("Boom"); 
   } 
 
   public static void m4() { } 
 
   @Test public static void m5() { } 
 
   public static void m6() { } 
 
   @Test public static void m7() { 
        throw newRuntimeException("Crash"); 
   } 
 
   public static void m8() { } 
  } 
 
  这里是测试工具:
  import java.lang.reflect.*; 
 
  public class RunTests { 
  public static void main(String[] args)throws Exception { 
  int passed = 0, failed = 0; 
    /*经典代码*/
  for (Method m : Class.forName(args[0]).getMethods()){ 
  if (m.isAnnotationPresent(Test.class)){ 
  try { 
  m.invoke(null); 
  passed++; 
  } catch (Throwable ex) { 
  System.out.printf("Test %sfailed: %s %n", m, ex.getCause()); 
  failed++; 
  } 
  } 
} 
System.out.printf("Passed: %d, Failed %d%n", passed,failed); 
} 
} 

 

  这个工具用一个类名作为参数,遍历这个类中的所有方法,并调用其中被加了@Test注释的方法。如果一个方法抛出了一个异常,那么这个测试就失败了,最终的测试结果被打印了出来。下面是程序运行的结果: 

$ java RunTests Foo 

Test public static void Foo.m3() failed:java.lang.RuntimeException: Boom 

Test public static void Foo.m7() failed:java.lang.RuntimeException: Crash 

Passed: 2, Failed 2 

  虽然这个测试工具只是一个玩具,但他显示了注释的强大的功能。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值