@interface是用來自定義JAVA Annotation的語法,普通的開發人員可能很少用到它,但是它的功能很強大,本文將具體介紹@interface的用法!
@interface是用來自定義註釋類型的,如果你不瞭解Java註釋,可以參閱上一篇文章:”JDK5.0註釋(Annotation)的用法”。
一般的應用程序開發人員可能從不需要定義一個註釋類型,但定義我們自己的註釋類型並不複雜。註釋類型的定義跟定義一個接口相似,我們需要在 interface這個關鍵字前面加上一個@符號,即@interface。註釋中的每一個方法定義了這個註釋類型的一個元素,註釋中方法的聲明中一定不能包含參數,也不能拋出異 常;方法的返回值被限制爲簡單類型、String、Class、emnus、註釋,和這些類型的數組。方法可以有一個缺省值。這裏是一個註釋類型定義的例 子:
/**
* Describes the Request-For-Enhancement(RFE) that led
* to the presence of the annotated API element.
*/
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)註釋類型,例如
/**
* Indicates that the specification of the annotated API element
* is preliminary and subject to change.
*/
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 Propulsion Systems”)
public class OscillationOverthruster { … }
爲了將上面提到的東西結合在一起,我們創建了一個簡單的基於註釋的測試框架。首先我們需要一個標記註釋類型用以說明一個方法是一個測試方法,並被測試工具執行。
import java.lang.annotation.*;
/**
* Indicates that the annotated method is a test method.
* This annotation should be used only on parameterless static methods.
*/
@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() { }
}
再來看看以下源碼:
/**
* @since Common Annotations 1.0
*/
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Resource {
public enum AuthenticationType {
CONTAINER,
APPLICATION
}
public String name() default “”;
/**
* Uses generics since Common Annotations 1.2.
*/
public Class