文章目錄
- 一、概念
- 二、分類
- 三、JDK的注解
- 3.1 JDK的注解可用來編寫文檔說明:
- 3.2 JDK的注解可進行編譯檢查
- 3.2 JDK中的元注解
- 四、第三方的注解
- 五、自定義注解
- 六、注解案例
- 七、總結
一、概念
- 注解是一種代碼級别的說明,是JDK1.5以後引入的一個特性。
- 它可以聲明在包、類、字段、方法、局部變量、方法參數等的前面,用來對這些元素進行說明與注釋。
- 注解以@開頭,比如 @Autowired,@Service,@Controller,@Override ,@Test,@Value 等等
二、分類
-
注解按照來源劃劃分,可以分為
1、JDK的注解。
2、第三方的注解。
3、自定義注解。
三、JDK的注解
3.1 JDK的注解可用來編寫文檔說明:
- 通過代碼裡辨別的注解可生成JavaDoc文檔
/**
* 使用注解使得程式注釋可生成JavaDoc
*
* @author zhuhuix
* @date 2020-09-06
* @version 1.0
*/
public class AnnotationDemo1 {
/**
* 兩數之和
* @param a 加數1
* @param b 加數2
* @return 傳回兩數相加之各
*/
public int add(int a,int b){
return a+b;
}
}

3.2 JDK的注解可進行編譯檢查
- 通過代碼裡辨別的注解讓編譯器能夠實作基本的編譯檢查。
- @Override : 檢測被該注解标注的主法是否是繼承自父類或者接口的。
- @Deprecated:該注解标注的内容已過時。
- @SuppressWarnings :壓制警告。
/**
* 使用注解讓編譯器進行編譯檢查
*
* @author zhuhuix
*/
public class AnnotationDemo2 {
// 繼承自父類
@Override
public String toString() {
return super.toString();
}
// 過時
@Deprecated
public int add(int a,int b){
return a+b;
}
// 壓制警告
@SuppressWarnings("all")
public int divide(int a,int b){
return a/b;
}
}
3.2 JDK中的元注解
- @Target (注解的作用目标)
- @Retention (注解的生命周期)
- @Document (該注解标記的元素可以被Javadoc 或類似的工具文檔化)
- @Inherited (使用了@Inherited注解的注解,所标記的類的子類也會擁有這個注解)
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {
}
四、第三方的注解
- 比如Spring架構中用到了大量的注解
注解 | 作用 |
@SpringBootApplication | 讓spring boot自動給程式進行必要的配置 |
@Controller | 用于定義控制器類 |
@RequestMapping | 提供路由資訊 |
@Import | 用來導入其他配置類 |
@Autowired | 自動導入依賴的bean |
… |
五、自定義注解
- 首先我們需要了解注解的本質:其實就是一個接口,該接口預設繼承Annotation接口
public interface MyAnnotation extends java.lang.annotation.Annotation{
}
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
- 自定義注解的格式:
/**
* 元注解
* 修飾符 @interface 注解名稱 {
* 屬性聲明A
* 屬性聲明B
* 屬性聲明...
* }
*
* 修飾符:通路修飾符必須為public,不寫預設為pubic;
* 關鍵字:必須為@interface;
*
* 屬性:注解中内容,可以了解成自定義接口的實作部分;
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
/**
* 注解的屬性聲明的兩種形式
* type elementName();
* type elementName() default value;
* type[] elementName();
*/
String value1() ;
String value2() default "test";
String[] value3();
}
- 自定義注解的屬性的傳回值類型必須滿足以下類型:
- 基本資料類型
- String類型
- 枚舉類型
- 注解類型
- 以上類型的數組
- 屬性指派必須滿足以下條件:
- 使用自定義注解時,沒有預設值的屬性必須給屬性指派;
- 如果屬性使用了default關鍵字賦予了預設值,則注解在使用時可以不進行指派。
- 數組指派時,需要用大括号進行包裹。
/**
* 使用自定義注解,沒有預設值的屬性必須指派
*/
@MyAnnotation(value1 = "111",value3 = {"a","b"})
public class AnnotationDemo3 {
}
六、注解案例
- 自定義一個注解,用來标注代碼檢測
/**
* 自定義代碼檢測注解
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCheck {
}
- 編寫一段源代碼,用自定義注解進行标注
/**
* 源代碼--使用自定義注解進行标注
*/
public class Source {
@MyCheck
public int method1(){
return 1+0;
}
@MyCheck
public int method2(){
return 1/0;
}
}
- 編寫一個測試架構,進行異常檢測
/**
* 使用自定義代碼檢查注解檢查代碼中是否存在BUG
*/
public class SourceCheck {
public static void main(String[] args) {
Source source = new Source();
Class clazz = source.getClass();
Method[] methods = clazz.getMethods();
for (Method method : methods){
if (method.isAnnotationPresent(MyCheck.class)){
try{
method.invoke(source);
} catch (Exception e) {
e.printStackTrace();
System.out.println(method.getName()+" 發生異常 :"+e.getCause().getMessage());
}
}
}
}
}
七、總結
- 在項目開發過程中,我們一般會使用注解(比如使用Spring架構的注解),而不是自定義注解。
- 注解一般是給編譯器或解析程式(比如上述案例中的代碼檢測架構)用。
- 注解不是程式的一部分,可以了解為注解就是一個标簽。