@interface是用来自定义JAVA Annotation的语法,普通的开发人员可能很少用到它,但是它的功能很强大,本文将具体介绍@interface的用法!
@interface是用来自定义注释类型的,如果你不了解Java注释,可以参阅上一篇文章:"JDK5.0注释(Annotation)的用法"。 一般的应用程序开发人员可能从不需要定义一个注释类型,但定义我们自己的注释类型并不复杂。注释类型的定义跟定义一个接口相似,我们需要在 interface这个关键字前面加上一个@符号,即@interface。注释中的每一个方法定义了这个注释类型的一个元素,注释中方法的声明中一定不 能包含参数,也不能抛出异 常;方法的返回值被限制为简单类型、String、Class、emnus、注释,和这些类型的数组。方法可以有一个缺省值。这里是一个注释类型定义的例 子:
-
-
-
-
- public @interface RequestForEnhancement {
- int id();
- String synopsis();
- String engineer() default "[unassigned]";
- String date(); default "[unimplemented]";
- }
一旦定义好了一个注释类型,你就可以用来作注释声明。注释一中特殊的修饰符,在其他修饰符(比如public,static,或者final等) 使用地方都可以使用。按照惯例,注释应该放在其他修饰符的前面。注释的声明用@符号后面跟上这个注释类型的名字,再后面跟上括号,括号中列出这个注释中元 素/方法的key-value对。值必须是常量。这里是一个例子,使用上面定义的注释类型:
- @RequestForEnhancement(
- id = 2868724,
- synopsis = "Enable time-travel",
- engineer = "Mr. Peabody",
- date = "4/1/3007"
- )
- public static void travelThroughTime(Date destination) { ... }
没有元素/方法的注释被成为标记(marker)注释类型,例如
-
-
-
-
- public @interface Preliminary { }
标记注释在使用的时候,其后面的括号可以省略,例如
- @Preliminary public class TimeTravel { ... }
如果注释中仅包含一个元素,这个元素的名字应该为value,例如:
-
-
-
- public @interface Copyright { String value(); }
如果元素的名字为value,使用这个注释的时候,元素的名字和等号可以省略,如:
- @Copyright("2002 Yoyodyne Propulsion Systems")
- public class OscillationOverthruster { ... }
为了将上面提到的东西结合在一起,我们创建了一个简单的基于注释的测试框架。首先我们需要一个标记注释类型用以说明一个方法是一个测试方法,并被测试工具执行。
- import java.lang.annotation.*;
-
-
-
-
- @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 new RuntimeException("Boom");
- }
- public static void m4() { }
- @Test public static void m5() { }
- public static void m6() { }
- @Test public static void m7() {
- throw new RuntimeException("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 %s failed: %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
虽然这个测试工具只是一个玩具,但他显示了注释的强大的功能。 |
转载地址:http://www.95582.net/a/J2EE/java/2010/0514/66.html