Java註解學習總結

一:註解基礎學習

註解從含義上講是一種元數據,本質上只是對代碼的一種註釋說明,因爲有了註解的解析纔有了相應的功能。如果沒有註解解析產生功能,它還不如註釋清晰。從結構上看,註解編譯後就是一個接口

元註解

元註解:元註解是一種基本註解,在定義註解時使用,主要定義註解的作用域,生命週期等等

  1. @Retention:定義註解的生命週期
    • RetentionPolicy.SOURCE 註解只在源碼階段保留,在編譯器進行編譯時它將被丟棄忽視。
    • RetentionPolicy.CLASS 註解只被保留到編譯進行的時候,它並不會被加載到 JVM 中。
    • RetentionPolicy.RUNTIME 註解可以保留到程序運行的時候,它會被加載進入到 JVM 中,所以在程序運行時可以獲取到它們
  2. @Documented
    將註解中的元素包含到 Javadoc 中去。
  3. @Target
    限定了運用的場景。方法,字段,類。ElementType列舉了枚舉值表示作用域
  4. @Inherited
    如果一個註解使用@Inherited標記,那麼使用當前註解的類的子類自動添加當前註解(子類沒有顯式使用註解)
  5. @Repeatable
    java8開始引入,定義的註解可以在同一個地方重複使用

註解的定義和屬性

註解定義關鍵字是@interface,註解只有成員變量,沒有方法。方法名定義了該成員變量的名字,其返回值定義了該成員變量的類型
在這裏插入圖片描述
定義了 TestAnnotation 這個註解中擁有 id 和 msg 兩個屬性。在使用的時候,我們應該給它們進行賦值。賦值的方式是在註解的括號內以 value=”” 形式,多個屬性之前用 ,隔開。
在這裏插入圖片描述
注意點:

  1. 定義屬性時它的類型必須是 8 種基本數據類型外加 類、接口、註解及它們的數組
  2. 可以給屬性設置默認值
public int id() default -1;
  1. 一個註解內僅僅只有一個名字爲 value 的屬性時,應用這個註解時可以直接接屬性值填寫到括號內。如果有多個屬性,使用時省略屬性名默認指的就是value屬性

二:編譯時解析註解

在使用javac編譯java代碼時,通過APT(註解處理器)技術獲取.java文件中的註解信息,生成新的java代碼(可以使用javapoet生成代碼),可以實現一些功能。例如:lombok工具包

使用APT;
步驟1:繼承AbstractProcessor,重寫process方法
使用@AutoService生成META-INF\services\javax.annotation.processing.Processor

@AutoService的pom

<dependency>
	<groupId>com.google.auto.service</groupId>
	<artifactId>auto-service</artifactId>
	<version>1.0-rc6</version>
</dependency>

使用:
在這裏插入圖片描述
process生成helloworld

public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
		 System.out.println("------ process -----");
	        //MethodSpec這個類是要引入'com.squareup:javapoet:1.8.0'包,方便通過代碼創建java文件
	        MethodSpec main = MethodSpec.methodBuilder("main")
	                //.addModifiers(Modifier.PUBLIC, Modifier.STATIC)
	                .returns(void.class)
	                .addParameter(String[].class, "args")
	                .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
	                .build();
	        TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
	                //netstat -an | grep .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
	                .addMethod(main)
	                .build();

	        JavaFile javaFile = JavaFile.builder("com.txd.annotaionlearn", helloWorld)
	                .build();
	        try {
	            //這裏的輸出要在Gradle Console中看
	            javaFile.writeTo(System.out);
                javaFile.writeTo(new File("E:\\10.workspace\\2.ST(4.0)\\test\\src\\main\\java\\com\\txd\\annotaionlearn\\model"));
	        } catch (IOException e) {
	            e.printStackTrace();
	        }
	        return false;
	}

編譯,安裝到本地倉庫,clean install

步驟2:在maven工程中使用以上的自定義註解處理器,涉及2個插件
maven-processor-plugin和maven-compiler-plugin
此處我通過maven-compiler-plugin來使用自定義annotationprocessor
在這裏插入圖片描述
然後,mvn clean compile
會發現在控制檯上:
在這裏插入圖片描述
本地生成helloworld文件
在這裏插入圖片描述

此次生成代碼用到了java類庫javapoet

三:運行時解析註解

註解類型必須是:@Retention(RetentionPolicy.RUNTIME)
運用反射技術提取註解:使用Class 對象的幾個方法

public boolean isAnnotationPresent(Class<? extends Annotation> annotationClass){} ;
public <A extends Annotation> A getAnnotation(Class<A> annotationClass) {};
public Annotation[] getAnnotations() {};

然後就可以獲取註解上的參數,做邏輯處理

四:spi使用@AutoService

spi在很多地方已經有使用:jdbc4.0以後,dubbo

五:常見的操作源代碼字節碼的庫

字節碼:javasist,cglib,ASM
源碼:Javapoet

五:參考博客

  1. https://www.cnblogs.com/guyuehuanhuan/p/9185899.html
  2. https://juejin.im/entry/585617d6128fe1006994f992
  3. https://www.jianshu.com/p/c04619b37440
  4. https://blog.csdn.net/jjxojm/article/details/90349756
  5. https://www.jianshu.com/p/086fe09188ea
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章