一、註解按照運行機制分類:
源碼註解:註解只在源碼中存在,.class文件就沒了
編譯時註解:註解在源碼和.class文件裏都存在(@Override、@Deprecate)
運行時註解:程序運行時還起作用(@Autowired)
二、註解按照使用的方式和用途分類。
(1)內建註解
又稱爲基本註解,位於java.lang包下。
內建註解有三個:
1、檢驗重寫父類方法:@Override
2、標識方法已經過時:@Deprecated
3、取消編譯器警告:@SurppressWarnings
(2)元註解
元註解就是在註解上添加的註解。
位置:元註解位於java.lang.annotation子包中。
作用:用於修飾其他註解。
元註解有四個:
@Retention,@Target,@Documented,@Inherited
Java SE 8引入@Repeatable元註解,表示註解可以重複使用(同一個方法或類上重複使用)
(3)自定義註解
需要用到關鍵字@interface來定義
三、自定義註解
/**
* @author: lizhilong
* @date: 2017-12-05 10:50:54
*/
// 元註解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Sign {
// 成員以無參無異常的方式聲明
String sign();
String author() default "";
int age() default 18;
}
注意:
1、成員類型只能是基本類型、String、Class、Annotation、Enumeration這幾個
2、如果註解只有一個成員,則成員名必須(約定俗成)取名爲value()
3、註解可以沒有成員,沒有成員的註解成爲標識註解
4、如果成員沒有默認值,則使用的時候必須要填
四、元註解的作用:
@Retention:用來描述被修飾的註解的生命週期。
@Target:用於指定被修飾的註解的適用範圍,即被修飾的註解可以用來修飾哪些程序元素。
@Documented:用於指定被修飾的註解將被javadoc工具提取成文檔。
@Inherited:用於指定被@Inherited修飾的註解具有繼承性。
@Retention 中參數
@Retention(RetentionPolicy.SOURCE):註解僅存在於源碼中,在class字節碼文件中不包含
@Retention(RetentionPolicy.CLASS):默認的保留策略,註解會在class字節碼文件中存在,但運行時無法獲得
@Retention(RetentionPolicy.RUNTIME):註解會在class字節碼文件中存在,在運行時可以通過反射獲取到
@Target中參數
@Target(ElementType.TYPE): 接口、類、枚舉、註解
@Target(ElementType.FIELD): 字段、枚舉的常量
@Target(ElementType.METHOD): 方法
@Target(ElementType.PARAMETER): 方法參數
@Target(ElementType.CONSTRUCTOR): 構造函數
@Target(ElementType.LOCAL_VARIABLE): 局部變量
@Target(ElementType.ANNOTATION_TYPE): 註解
@Target(ElementType.PACKAGE): 包
五、註解的使用
自定義註解使用的類:
/**
* @author: lizhilong
* @date: 2017-12-05 16:58:29
*/
@Sign(author = "lizhilong", sign = "class sign")
public class Teacher implements Person {
@Override
@Sign(author = "lizhilong", sign = "method sign")
public void eat() {
System.out.println("吃了....");
}
}
註解獲取:
package vip.lizhilong.lambda.test;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.junit.Test;
import vip.lizhilong.lambda.annotation.Sign;
/**
* @author: lizhilong
* @date: 2017-12-05 17:02:12
*/
public class AnnotationTest {
@SuppressWarnings({"rawtypes", "unchecked"})
@Test
public void Test(){
try {
// 1.使用類加載器
Class clazz = Class.forName("vip.lizhilong.lambda.impl.Teacher");
// 2.找到類上的註解(兩種)
// 第一種方式
boolean isExit = clazz.isAnnotationPresent(Sign.class);
if (isExit) {
// 3.拿到註解實例
Sign sign = (Sign)clazz.getAnnotation(Sign.class);
System.out.println(sign.author() + "----" + sign.sign() + "----" + sign.age());
}
// 第二種方式
Annotation[] annotations = clazz.getAnnotations();
for (Annotation annotation : annotations) {
// instanceof 判斷是否爲父子關係,也可以判斷類型
if (annotation instanceof Sign) {
Sign sign = (Sign) annotation;
System.out.println(sign.author() + "----" + sign.sign() + "----" + sign.age());
}
}
// 4.找到方法上的註解
Method[] methods = clazz.getMethods();
for (Method method : methods) {
isExit = method.isAnnotationPresent(Sign.class);
if (isExit) {
Sign sign = method.getAnnotation(Sign.class);
System.out.println(sign.author() + "----" + sign.sign() + "----" + sign.age());
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
打印結果
lizhilong----class sign----18
lizhilong----class sign----18
lizhilong----method sign----18
這些事註解的創建和使用的基本方式,
應用場景:登陸、權限攔截、定時任務管理
下篇會講註解在項目中的使用
如何在在項目中使用自定義註解