日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java注释和注解_深入理解JAVA注解(Annotation)以及自定义注解

發布時間:2023/12/10 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java注释和注解_深入理解JAVA注解(Annotation)以及自定义注解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java 注解(Annotation)又稱 Java 標注,是 JDK5.0 引入的一種注釋機制。Java 語言中的類、方法、變量、參數和包等都可以被標注。注解可以看作是一種特殊的標記,在程序在編譯或者運行時可以檢測到這些標記而進行一些特殊的處理。本文對 Annotation 進行了整理帶你一步一步解開Java注解的神秘面紗并實現自己的自定義注解。

元注解

元注解的作用就是負責注解其他注解。Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它 annotation類型作說明。他們位于java.lang.annotation包中。

元注解下

@Target

@Retention

@Documented

@Inherited

@Target:

源碼如下

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Target {

/**

* Returns an array of the kinds of elements an annotation type

* can be applied to.

* @return an array of the kinds of elements an annotation type

* can be applied to

*/

ElementType[] value();

}

它表明該注解可以應用的java元素類型

ElementType.TYPE:應用于類、接口(包括注解類型)、枚舉

ElementType.FIELD:應用于屬性(包括枚舉中的常量)

ElementType.METHOD:應用于方法

ElementType.PARAMETER:應用于方法的形參

ElementType.CONSTRUCTOR:應用于構造函數

ElementType.LOCAL_VARIABLE:應用于局部變量

ElementType.ANNOTATION_TYPE:應用于注解類型

ElementType.PACKAGE:應用于包

ElementType.TYPE_PARAMETER:1.8版本新增,應用于類型變量)

ElementType.TYPE_USE:1.8版本新增,應用于任何使用類型的語句中(例如聲明語句、泛型和強制轉換語句中的類型)

@Retention:源碼如下

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Retention {

/**

* Returns the retention policy.

* @return the retention policy

*/

RetentionPolicy value();

}

它需要在什么級別保存該注釋信息,用于描述注解的生命周期

RetentionPolicy.SOURCE:在源文件中有效(即源文件保留),編譯時被丟棄,不包含在類文件中

RetentionPolicy.CLASS:在class文件中有效(即class保留),JVM加載時被丟棄,包含在類文件中,默認值

RetentionPolicy.RUNTIME:在運行時有效(即運行時保留),由JVM 加載,包含在類文件中,在運行時可以被獲取到

@Documented:

源碼如下

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Documented {

}

它表明該注解標記的元素可以被Javadoc或類似的工具文檔化,@Documented是一個標記注解,沒有成員。

@Inherited源碼如下

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target(ElementType.ANNOTATION_TYPE)

public @interface Inherited {

}

表明使用了@Inherited注解的注解,所標記的類的子類也會擁有這個注解是不是有點難以理解,我們舉個例子

自定義注解

自定義注解 @InheritedTest

package com.example.demo.annotation;

import java.lang.annotation.*;

@Target(ElementType.TYPE)

@Retention(RetentionPolicy.RUNTIME)

@Inherited public @interface InheritedTest {

}

新建父類 Parent

package com.example.demo.test;

import com.example.demo.annotation.InheritedTest;

@InheritedTest

public class Parent {

public void testMethod(){

System.out.println("Parent " + Parent.class.isAnnotationPresent(InheritedTest.class));

}

}

新建子類 Child

package com.example.demo.test;

import com.example.demo.annotation.InheritedTest;

public class Child extends Parent {

public static void main(String[] args) {

Child child = new Child();

child.testMethod();

System.out.println("Child " + Child.class.isAnnotationPresent(InheritedTest.class));

}

}

isAnnotationPresent()方法表示指定注釋類型的注釋是否存在于此元素上,是則返回true,否則返回false。

我們運行子類可以看到如下結果

在子類中我們并沒有使用 @InheritedTest 注解,結果一樣返回了true,下面我們把InheritedTest中的@Inherited注釋掉,然后再運行子類結果如下

可以看到,現在返回了false。

簡單示例

package com.example.demo.annotation;

import java.lang.annotation.*;

@Target(ElementType.FIELD)

@Documented()

@Retention(RetentionPolicy.RUNTIME)

public @interface Color {

String value() default "";

}

以上我們就自定義了一個注解@Color,該注解應用于屬性之上,在運行時有效,并且可以生成api文檔。使用方法

package com.example.demo.test;

import com.example.demo.annotation.Color;

public class Cat {

@Color("黃色")

private String color;

public String getColor(){

return this.color;

}

public void setColor(String color){

this.color = color;

}

public static void main(String args[]){

Cat cat = new Cat();

System.out.println(cat.getColor());

}

}

這里我們定義了一個Cat類,里面有一個屬性color,我們使用@Color(“黃色”)給他賦值為黃色,然后執行這個類打印出結果如下

什么?怎么為null呢,是不是感覺被忽悠了?因為我們只是定義了這個注解,但是卻沒寫怎么處理被這個注解標記了字段,這個時候打印出來的當然為null了。

現在我們來修改一下Cat類

public static void main(String args[]) throws NoSuchFieldException {

Cat cat = new Cat();

Color color = Cat.class.getDeclaredField("color").getAnnotation(Color.class);

if (color != null) {

String value = color.value();

cat.setColor(value);

}

System.out.println(cat.getColor());

}

打印結果如下

以上我們簡單的處理了下注解,并把處理邏輯放在了main方法中,其實這是不合理的。我們通過用下面的例子,使用Spring AOP面向切面編程思想來自定義日志注解。

自定義注解

自定義日志注解@SysLog

package com.example.demo.annotation;

import java.lang.annotation.*;

@Target(ElementType.METHOD)

@Documented()

@Retention(RetentionPolicy.RUNTIME)

public @interface SysLog {

String value() default "";

}

定義切面

package com.example.demo.aspect;

import com.example.demo.annotation.SysLog;

import lombok.extern.slf4j.Slf4j;

import org.aspectj.lang.JoinPoint;

import org.aspectj.lang.annotation.After;

import org.aspectj.lang.annotation.Aspect;

import org.aspectj.lang.annotation.Before;

import org.aspectj.lang.annotation.Pointcut;

import org.aspectj.lang.reflect.MethodSignature;

import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect

@Component

@Slf4j

public class SysLogAspect {

@Pointcut("@annotation(com.example.demo.annotation.SysLog)")

private void logPointCut() {

}

@Before("logPointCut()")

private void before(JoinPoint joinPoint){

String className = joinPoint.getTarget().getClass().getName();

MethodSignature signature = (MethodSignature) joinPoint.getSignature();

String methodName = signature.getName();

Method method = signature.getMethod();

SysLog sysLog = method.getAnnotation(SysLog.class);

String value = sysLog.value();

log.info(className);

log.info(methodName);

log.info(value);

log.info("這里我們就可以自己處理了");

}

@After("logPointCut()")

private void after(){

log.info("執行之后");

}

}

測試注解

package com.example.demo.test;

import com.example.demo.annotation.SysLog;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

@RestController @RequestMapping("/log")

public class LogTest {

@SysLog("測試日志打印")

@RequestMapping("/test")

public String testLog(){

return "這里是測試自定義注解日志打印";

}

}

用postman訪問localhost:8080/log/test結果如下

控制臺日志打印如下

以上我們就完成了自定日志注解的實現,以上例子只是示例,實際開發中還可以又更多功能實現。好了,本文介紹就到這里了,如有錯誤請提出指正。

總結

以上是生活随笔為你收集整理的java注释和注解_深入理解JAVA注解(Annotation)以及自定义注解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。