ITEEDU

Java Gossip: 自订 Annotation 型态

您可以自订Annotation型别,并使用这些自订的Annotation型别在程序代码中使用 Annotation,这些Annotation将提供信息给您的程序代码分析工具。

首先来看看如何定义Marker Annotation,也就是Annotation名称本身即提供信息,对于程序分析工具来说,主要是检查是否有Marker Annotation的出现,并作出对应的动作。

要定义一个Annotation所需的动作,就类似于定义一个接口(interface),只不过您使用的是@interface,例如定义一个 Debug Annotation型态:

Debug.java
package onlyfun.caterpillar;
public @interface Debug {} 

由于是个Marker Annotation,所以没有任何的成员在里头,编译完成后,您就可以在程序代码中使用这个Annotation了,例如:

SomeObject.java
package onlyfun.caterpillar;
import java.util.*;
public class SomeObject {
	@Debug?
	public void doSomething() {
		// ....
	}
}

接着来看看如何定义一个Single-value Annotation,它只有一个成员,名称为value,例如您可以提供Debug Annotation更多信息:

Debug.java
package onlyfun.caterpillar;
public @interface Debug {
	String value();
}

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

SomeObject.java
package onlyfun.caterpillar;
import java.util.*;
public class SomeObject {
	@Debug("unit test")
	public void doSomething() {
		// ....
	}
}

@Debug("unit test")实际上是@Debug(value="unit test")的简便写法,如果是数组值,例如:

Debug.java
package onlyfun.caterpillar;
public @interface Debug {
	String[] value();
}

则使用Annotation时,可以写成@Debug({"value1", "value2"}),或是@Debug(value={"value1", "value2"})。

您也可以对成员设定默认值,使用default关键词即可,例如:

Debug.java
package onlyfun.caterpillar;
public @interface Debug {
	String value() default "none";
}

这么一来如果您使用@Debug时没有指定值,则预设就是"none"。

您也可以为Annotation定义额外的成员,以提供额外的信息给分析工具,例如:

Debug.java
package onlyfun.caterpillar;
public @interface Debug {
	public enum Level {NONE, UNIT, INTEGRATION, FUNCTION};
	Level level() default Level.NONE;
	String name();
	String tester();
}

则您可以如下使用这个Annotation:

SomeObject.java
package onlyfun.caterpillar;
import java.util.*;
public class SomeObject {
	@Debug(
	level = Debug.Level.UNIT,
	name = "some test",
	tester = "justin"
	)
	public void doSomething() {
		// ....
	}
}

@interface实际上是自动继承自java.lang.annotation.Annotation,所以定义Annotation时不能继承其它 Annotation或是interface。