【JAVA基础篇】注解
一、什么是注解?
注解是元數據,所謂元數據就是描述數據的數據。
在annotation誕生之前(jdk1.5誕生了注解),甚至之后,xml被廣泛的由于描述元數據。但是后來,有一些應用開發工程師和架構師覺得它越來越難以維護了,他們覺得需要一種和代碼緊耦合的東西,而不是xml配置和代碼是松耦合的(某些情況下甚至是完全分離的),于是annotation誕生了。
假如你想為應用設置很多的常量或參數,這種情況下,XML是一個很好的選擇,因為它不會同特定的代碼相連。如果你想把某個方法聲明為服務,那么使用Annotation會更好一些,因為這種情況下需要注解和方法緊密耦合起來,開發人員也必須認識到這點。
目前,許多框架將XML和Annotation兩種方式結合使用,平衡兩者之間的利弊。
二、使用注解的好處
三、注解的分類
3.1、元注解
用來定義注解的注解,@interface、@Target、@Retention、@Inherited
| 注解 | 作用 |
| @interface | 定義注解 |
| @Target | 聲明注解的使用目標,說明這個可以在類型上使用,還是屬性、還是方法、還是參數 |
| @Retention | 注解應該如何去保留,是在源碼中保留,還是在字節碼文件中保留,還是在運行時保留 |
| @Inherited | 子類是否繼承父類在類上定義的注解 |
3.2、內置注解
jdk定義的一些注解,還有很多其他的,這里只列舉一部分:@SuppressWarnings、@Deprecated、@Override、@Documented、@FunctionaInterface、@SafeVarargs、@version、@author、@param、@exception、@return
| @SuppressWarnings | 忽略警告 |
| @Deprecated | 棄用 |
| @Override | 說明此方法重寫父類的方法 |
| @Documented | 生成javadoc,生成javadoc時默認是不生成注解說明的,但是如果使用了@Documented來定義這個注解,那么將會生成注解說明 |
3.3、自定義注解
使用@interface來自定義一個注解
四、注解使用示例
我們先來定義幾個注解
4.1、注解定義
package org.cc.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface Controller {String value(); } package org.cc.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Inherited @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface Inject {String value(); } package org.cc.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Inherited @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface Parameter {String value() default ""; } package org.cc.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Inherited @Target({ElementType.FIELD,ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface Permission {String value() default "root"; } package org.cc.annotation;import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;@Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) public @interface Required { }4.2、使用注解
package org.cc.annotation.use;import org.cc.annotation.Controller; import org.cc.annotation.Inject; import org.cc.annotation.Parameter; import org.cc.annotation.Permission; import org.cc.annotation.Required; /*** 定義一個類,來使用剛剛定義的注解* @author cc**/ @Controller("testController") public class TestController {@Inject("injectStr")private String injectStr;@Permission("testPermission")public void test(@Parameter("param") @Required String param,String param2){} } package org.cc.annotation.use;/*** TestController類的子類* @author cc**/ public class SubTestController extends TestController{private String injectStr;public void test(String param,String param2){} }4.3、解析注解
package org.cc.annotation.use;import java.lang.annotation.Annotation; import java.lang.reflect.Field;import org.cc.annotation.Controller; import org.cc.annotation.Inject;/*** 使用反射來解析注解* @author cc**/ public class JXAnnotation {public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, SecurityException, NoSuchMethodException {Class clazz = Class.forName("org.cc.annotation.use.TestController");Annotation[] annotations = clazz.getAnnotations();//得到指定類的所有注解for (Annotation a: annotations ) {System.out.println(a);}Controller c = (Controller)clazz.getAnnotation(Controller.class);//得到類特定的注解System.out.println(c.value());Field f = clazz.getDeclaredField("injectStr");Inject inject = f.getAnnotation(Inject.class);System.out.println(inject.value());Class clazz1 = Class.forName("org.cc.annotation.use.SubTestController");Controller c1 = (Controller)clazz1.getAnnotation(Controller.class);//得到類特定的注解System.out.println(c1);//因為定義Controller時沒有使用Inherited元注解,所以子類SubTestController并不會繼承父類的注解Controller//注意僅僅針對類,成員屬性和方法不受此注釋影響,就是說子類方法上的注解一定會繼承父類的注解}}五、定義和使用注解需要注意的地方
1、自定義注解我們可以看到有一行String value() ,類似于定義一個方法,這行代碼表示使用注解時必須指定value屬性值,像這樣:@Controller("testController")或者這樣寫@Controller(value="testController"),不能這樣寫:@Controller(),編譯會報錯。如果非要這樣使用,那么需要修改這個注解的定義,改成這樣String value() default "";或者直接將String value()這一行刪掉。
簡單描述就是:如果定義注解時定義了value屬性,那么使用時必須設置value屬性值,或者提供默認的屬性值。
2、定義注解時屬性是什么類型,那么使用注解時設置的屬性值必須跟定義的類型相同。下面這種情況也是可以的:定義時屬性值類型為字符串數組,然后使用時設置屬性值為字符串。
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的【JAVA基础篇】注解的全部內容,希望文章能夠幫你解決所遇到的問題。