一、注解按照運(yùn)行機(jī)制分類:
源碼注解:注解只在源碼中存在,.class文件就沒了
編譯時(shí)注解:注解在源碼和.class文件里都存在(@Override、@Deprecate)
運(yùn)行時(shí)注解:程序運(yùn)行時(shí)還起作用(@Autowired)
二、注解按照使用的方式和用途分類。
(1)內(nèi)建注解
又稱為基本注解,位于java.lang包下。
內(nèi)建注解有三個(gè):
1、檢驗(yàn)重寫父類方法:@Override
2、標(biāo)識(shí)方法已經(jīng)過時(shí):@Deprecated
3、取消編譯器警告:@SurppressWarnings
(2)元注解
元注解就是在注解上添加的注解。
位置:元注解位于java.lang.annotation子包中。
作用:用于修飾其他注解。
元注解有四個(gè):@Retention,@Target,@Documented,@Inherited
(3)自定義注解
需要用到關(guān)鍵字@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這幾個(gè)
2、如果注解只有一個(gè)成員,則成員名必須(約定俗成)取名為value()
3、注解可以沒有成員,沒有成員的注解成為標(biāo)識(shí)注解
4、如果成員沒有默認(rèn)值,則使用的時(shí)候必須要填
四、元注解的作用:
@Retention:用來描述被修飾的注解的生命周期。
@Target:用于指定被修飾的注解的適用范圍,即被修飾的注解可以用來修飾哪些程序元素。
@Documented:用于指定被修飾的注解將被javadoc工具提取成文檔。
@Inherited:用于指定被@Inherited修飾的注解具有繼承性。
@Retention 中參數(shù)
@Retention(RetentionPolicy.SOURCE):注解僅存在于源碼中,在class字節(jié)碼文件中不包含
@Retention(RetentionPolicy.CLASS):默認(rèn)的保留策略,注解會(huì)在class字節(jié)碼文件中存在,但運(yùn)行時(shí)無法獲得
@Retention(RetentionPolicy.RUNTIME):注解會(huì)在class字節(jié)碼文件中存在,在運(yùn)行時(shí)可以通過反射獲取到
@Target中參數(shù)
@Target(ElementType.TYPE): 接口、類、枚舉、注解
@Target(ElementType.FIELD): 字段、枚舉的常量
@Target(ElementType.METHOD): 方法
@Target(ElementType.PARAMETER): 方法參數(shù)
@Target(ElementType.CONSTRUCTOR): 構(gòu)造函數(shù)
@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("吃了....");
}
}
注解獲?。?/h5>
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.拿到注解實(shí)例
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 判斷是否為父子關(guān)系,也可以判斷類型
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();
}
}
}
打印結(jié)果
lizhilong----class sign----18
lizhilong----class sign----18
lizhilong----method sign----18
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.拿到注解實(shí)例
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 判斷是否為父子關(guān)系,也可以判斷類型
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
至此注解的創(chuàng)建和使用的基本方式就這么多,
下篇會(huì)講注解在項(xiàng)目中的使用
如何在在項(xiàng)目中使用自定義注解