Java注解
注解為代碼提供元數據, 作為元數據, 注解不直接影響代碼執(zhí)行
1.注解的語法
// 注解和class, interface一樣, 是java語言中的一種類
// 注解是通過@interface定義的
public @ interface TestAnnotation
{
//
}
2.元注解
2.1 元注解列表
就是使用在注解上的注解
元注解有 @Retention @Documented @Target @Inherited @Repeatable 5種
元注解 | 含義 | 選項 |
---|---|---|
@Retention | 標識注解的存活階段 | RetentionPolicy.SOURCE 源碼階段, 編譯后丟失 RetentionPolicy.CLASS 編譯階段, 加載到jvm后丟失 RetentionPolicy.RUNTIOME 運行階段, 運行時可以被獲取, 生命周期最長 |
@Target | 標識注解使用的地方, 多個使用位置可以使用 "," 分割 | ElementType.ANNOTATION_TYPE 給一個注解進行注解 ElementType.CONSTRUCTOR 給構造器進行注解 ElementType.FIELD 給屬性進行注解 ElementType.LOCAL_VARIABLE 給局部變量注解 ElementType.METHOD 給方法進行注解 ElementType.PACKAGE 給包進行注解 ElementType.PARAMETER 給方法的參數進行注解 ElementType.TYPE 給類, 接口, 枚舉, 注解進行注解 |
@Documented | 添加后JavaDoc工具處理完注解信息會被寫到api文檔中 | |
@Inherited | 被注解的類的子類是否能繼承該注解 | 注意: 被注解的接口的子類不會繼承該注解 |
@Repeatable | 同一個位置該注解是否能被重復使用 |
2.2 @Repeatable注解(java8添加)
// 申明Role注解可以重復
// 反射獲取的Role注解是多個, 多個Role被封裝成RoleCan中
@ Repeatable(RoleCan.class)
public @interface Role
{
public String value();
}
// 申明Role注解的容器, 屬性是Role的數組
@ Retention(RetentionPolicy.RUNTIME)
@ Target({ElementType.TYPE, ElementType.FIELD})
public @interface RoleCan
{
Role[] value() default {};
}
3.注解的屬性
注解的屬性也就是注解的成員變量, 注解只有成員變量沒有方法, 注解的成員變量的聲明方式以 "無參函數" 的方式來申明, 這個無參函數的方法名就是成員變量的名稱
@ Retention(RetentionPolicy.RUNTIME)
@ Target({ElementType.TYPE, ElementType.FIELD})
public @interface TestAnnotation
{
// name就是該注解的成員變量, 默認值是zhangsam, public可以省略
public String name();
// 申明數組類型的成員變量
public String[] addrs();
}
給注解的屬性賦值
@ TestAnnotation(name = "zhangsam", addrs = {"無錫"})
public class Test
{
// 如果TestAnnotation注解的name屬性沒有默認值, 則會報錯, 需要手動賦值
// 如果TestAnnotation沒有屬性, 則括號可以省略
}
4.注解的提取
// 如果TestAnnotation注解的name屬性沒有默認值, 則會報錯, 需要手動賦值
// 如果TestAnnotation沒有屬性, 則括號可以省略
@ TestAnnotation(name = "zhangsam", addrs = {"wuxi"})
public class Test
{
// 定義在屬性上的注解
@ TestAnnotation(name = "lisi", addrs = {"changan"})
private String a;
public static void main(String[] args) throws NoSuchFieldException, SecurityException
{
// 提取類上的注解
boolean hasAnnotation = Test.class.isAnnotationPresent(TestAnnotation.class);
if (hasAnnotation)
{
// TestAnnotation annotation = Test.class.getAnnotation(TestAnnotation.class);
TestAnnotation[] annotations = Test.class.getAnnotationsByType(TestAnnotation.class);
for (TestAnnotation annotation : annotations)
{
System.out.println(annotation.name());
System.out.println(annotation.addrs());
}
}
// 提取屬性上的注解
Field a = Test.class.getDeclaredField("a");
a.setAccessible(true);
TestAnnotation annotationInField = a.getAnnotation(TestAnnotation.class);
System.out.println(annotationInField.name());
System.out.println(annotationInField.addrs());
}
}
5.注解的使用場景
- 提供信息給編譯器, 編譯器利用注解信息來檢測和探知信息
- 編譯時的處理, 軟件工具可以使用注解信息生成代碼
- 運行時處理