Java常見注解
JDK自帶注解
- @Override:重寫
- @Deprecated:過時
- @Suppvisewarnings:忽略警告
常見第三方注解 > Spring
- @Autowired
- @Service
- @Respository
常見第三方注解 > Mybatis
- @InsertProvider
- @UpdateProvider
- @Options
注解分類
按照運行機制分
- 源碼注解:注解只在源碼中存在,編譯成.class文件就不存在了。
- 編譯時注解:注解在源碼和.class文件中都存在梯浪。(@Override夯秃,@Deprecated祟剔,@Suppvisewarnings)
- 運行時注解:在運行階段還起作用搓彻,甚至?xí)绊戇\行邏輯空扎。(@Autowired)
按照來源分
- 來自JDK的注解
- 來自第三方的注解
- 自定義的注解
元注解
自定義注解
自定義注解語法要求
- 使用@interface關(guān)鍵字定義注解浅缸。
- 成員以無參無異常方式聲明枉疼,可以用default為成員指定一個默認(rèn)值皮假,成員類型是受限制的,包括基本數(shù)據(jù)類型骂维,String惹资,Class,Annotation航闺,Enumeration褪测。
- 如果注解只有一個成員猴誊,則成員必須取名為value(),在使用時可以忽略成員名和賦值號(=)侮措。
- 注解類可以沒有成員懈叹,沒有成員的注解稱為標(biāo)識注解。
- 元注解 @Target:注解的作用域分扎,包括CONSTRUCTOR(構(gòu)造方法聲明)澄成,F(xiàn)IELD (字段聲明),LOCAL_VARIABLE(局部變量聲明)畏吓,METHOD(方法聲明)墨状,PACKAGE(包聲明)审洞,PARAMETER(參數(shù)聲明)间护,TYPE(類,接口)。
- 元注解 @Retention:注解的生命周期巴粪,包括SOURCE(只在源碼顯示,編譯時會丟棄)粥谬,CLASS(編譯時會記錄到class中肛根,運行時忽略),RUNTIME(運行時存在漏策,可以通過反射讀扰烧堋)。
- 元注解 @Inherited:允許子類繼承掺喻。
- 元注解 @Documented:生成javadoc時會包含注解芭届。
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
String desc();
String author();
int age() default 18;
}
使用自定義注解
<注解名>(<成員名1> = <成員值1>, <成員名2> = <成員值2>, ...)
@Description(desc = "hello desc", author = "tom", age = 19)
public void test() {
}
解析注解
通過反射獲取類,函數(shù)或成員上的運行時注解信息感耙,從而實現(xiàn)動態(tài)控制程序的邏輯褂乍。
子類注解優(yōu)先級高于父類注解。
- 定義注解
import java.lang.annotation.*;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description2 {
String value();
}
- 引用注解
@Description2("I am class Person annotation")
public class Person {
@Description2("I am class Person : method name annotation")
public String name() {
return null;
}
@Description2("I am class Person : method age annotation")
public int age() {
return 0;
}
public void sing() {
}
}
@Description2("I am class Man annotation")
public class Man extends Person {
@Override
@Description2("I am class Man : method name annotation")
public String name() {
return super.name();
}
}
- 解析注解 & 運行結(jié)果
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws ClassNotFoundException {
// 使用類加載器加載類
Class<?> c = Class.forName("annotation.Man");
// 找到類上面的注解
boolean isPresent = c.isAnnotationPresent(Description2.class);
// 獲取注解實例
if (isPresent) {
Description2 desc2 = c.getAnnotation(Description2.class);
System.out.println(desc2.value());
}
// 找到方法上的注解
Method[] methods = c.getMethods();
// 獲取注解實例 1
for (Method method : methods) {
boolean isMPresent = method.isAnnotationPresent(Description2.class);
if (isMPresent) {
Description2 mDesc2 = method.getAnnotation(Description2.class);
System.out.println("1:" + mDesc2.value());
}
}
// 獲取注解實例 2
for (Method method : methods) {
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof Description2) {
Description2 desc2 = (Description2) annotation;
System.out.println("2:" + desc2.value());
}
}
}
}
}
I am class Man annotation
1:I am class Man : method name annotation
1:I am class Person : method age annotation
2:I am class Man : method name annotation
2:I am class Person : method age annotation