最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java的@Repeatable注解使用詳細解析

 更新時間:2024年02月02日 08:32:51   作者:小徐也要努力鴨  
這篇文章主要介紹了Java的@Repeatable注解使用詳細解析,java8新增了注解@Repeatable,在hibernate-validator的源碼注解如@MAX、@NotNull等中,有@Repeatable注解的使用,需要的朋友可以參考下

1 前言

java8新增了注解@Repeatable,在hibernate-validator的源碼注解如@MAX、@NotNull等中,有@Repeatable注解的使用,源碼示例如下:

/*
 * Jakarta Bean Validation API
 *
 * License: Apache License, Version 2.0
 * See the license.txt file in the root directory or <http://www.apache.org/licenses/LICENSE-2.0>.
 */
package javax.validation.constraints;
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE_USE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
import javax.validation.constraints.NotNull.List;
/**
 * The annotated element must not be {@code null}.
 * Accepts any type.
 *
 * @author Emmanuel Bernard
 */
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
@Retention(RUNTIME)
@Repeatable(List.class)
@Documented
@Constraint(validatedBy = { })
public @interface NotNull {
	String message() default "{javax.validation.constraints.NotNull.message}";
	Class<?>[] groups() default { };
	Class<? extends Payload>[] payload() default { };
	/**
	 * Defines several {@link NotNull} annotations on the same element.
	 *
	 * @see javax.validation.constraints.NotNull
	 */
	@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
	@Retention(RUNTIME)
	@Documented
	@interface List {
		NotNull[] value();
	}
}

2 使用

參考hibernate-validator注解,使用@Repeatable:

2.1 新建注解RepeaDemo

暫時不添加@Repeatable:

package com.xiaoxu.tool.demo;

import java.lang.annotation.*;

@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeaDemo {
    String id();
    String name();
}

新建demo類:

package com.xiaoxu.tool.demo;
import java.lang.reflect.Field;
import java.util.Arrays;
/**
 * @author xiaoxu
 * @date 2022-05-17
 * spring_boot:com.xiaoxu.tool.demo.TestRepeatable
 */
public class TestRepeatable {
    @RepeaDemo(id = "1001",name = "荔枝")
    private String fruit1;
    @RepeaDemo(id = "1002",name = "葡萄")
    private String fruit2;
    public static void demo1(){
        Class<?> a = TestRepeatable.class;
        Field[] fruits = a.getDeclaredFields();
        Arrays.stream(fruits).forEach(f->{
            if(f.isAnnotationPresent(RepeaDemo.class)){
                RepeaDemo anno = f.getAnnotation(RepeaDemo.class);
                String id = anno.id();
                String name = anno.name();
                System.out.printf("水果id:%s,水果名稱:%s%n",id,name);
            }
        });
    }
    public static void main(String[] args) {
        demo1();
    }
}

執(zhí)行結(jié)果如下:

水果id:1001,水果名稱:荔枝
水果id:1002,水果名稱:葡萄

但是問題是,如果希望在字段上增加多個注解,那么會提示Duplicate annotation.錯誤:

在這里插入圖片描述

于是考慮新增一個RepeaDemos注解,用于存儲@RepeaDemo注解數(shù)組,就可以達到多個注解的使用了,如下:

package com.xiaoxu.tool.demo;

import java.lang.annotation.*;

@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeaDemos {
    RepeaDemo[] repeaDemos();
}

修改TestRepeatable代碼:

package com.xiaoxu.tool.demo;

import java.lang.reflect.Field;
import java.util.Arrays;

/**
 * @author xiaoxu
 * @date 2022-05-17
 * spring_boot:com.xiaoxu.tool.demo.TestRepeatable
 */
public class TestRepeatable {
    @RepeaDemos(repeaDemos = {
        @RepeaDemo(id = "1001",name = "荔枝"),
        @RepeaDemo(id = "1003",name = "沃柑")
    })
    private String fruit1;

    @RepeaDemo(id = "1002",name = "葡萄")
    private String fruit2;

    public static void demo1(){
        Class<?> a = TestRepeatable.class;
        Field[] fruits = a.getDeclaredFields();
        Arrays.stream(fruits).forEach(f->{
            if(f.isAnnotationPresent(RepeaDemo.class)){
                RepeaDemo anno = f.getAnnotation(RepeaDemo.class);
                String id = anno.id();
                String name = anno.name();
                System.out.printf("水果id:%s,水果名稱:%s%n",id,name);
            }
        });
    }

    public static void demo2(){
        Class<?> a = TestRepeatable.class;
        Field[] fruits = a.getDeclaredFields();
        Arrays.stream(fruits).forEach(f->{
            if(f.isAnnotationPresent(RepeaDemos.class)){
                RepeaDemos anno = f.getAnnotation(RepeaDemos.class);
                RepeaDemo[] res= anno.repeaDemos();
                Arrays.stream(res).forEach(r-> System.out.printf("水果id:%s,水果名稱:%s%n",r.id(),r.name()));
            }
            if(f.isAnnotationPresent(RepeaDemo.class)){
                RepeaDemo anno = f.getAnnotation(RepeaDemo.class);
                String id = anno.id();
                String name = anno.name();
                System.out.printf("水果id:%s,水果名稱:%s%n",id,name);
            }
        });
    }
    public static void main(String[] args) {
        demo2();
    }
}

執(zhí)行結(jié)果如下:

水果id:1001,水果名稱:荔枝
水果id:1003,水果名稱:沃柑
水果id:1002,水果名稱:葡萄

2.2 @Repeatable注解使用

對于上述注解使用,@Repeatable注解的作用就是使得@RepeaDemo注解可以多個添加在字段上,而最外層無須包裹@RepeaDemos注解,當然,@RepeaDemos注解任然需要保留,修改如下:

修改@RepeaDemos注解(注意@RepeaDemos注解,必須改為value()才可以):

package com.xiaoxu.tool.demo;

import java.lang.annotation.*;

@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RepeaDemos {
    RepeaDemo[] value();
}

修改@RepeaDemo注解,增加@Repeatable,參數(shù)為RepeaDemos.class:

package com.xiaoxu.tool.demo;

import java.lang.annotation.*;

@Target(value = {ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(RepeaDemos.class)
@Documented
public @interface RepeaDemo {
    String id();
    String name();
}

修改demo類:

package com.xiaoxu.tool.demo;
import java.lang.reflect.Field;
import java.util.Arrays;
/**
 * @author xiaoxu
 * @date 2022-05-17
 * spring_boot:com.xiaoxu.tool.demo.TestRepeatable
 */
public class TestRepeatable {
//    @RepeaDemos(value = {
//        @RepeaDemo(id = "1001",name = "荔枝"),
//        @RepeaDemo(id = "1003",name = "沃柑")
//    })
    @RepeaDemo(id = "1001",name = "荔枝")
    @RepeaDemo(id = "1003",name = "沃柑")
    private String fruit1;
    @RepeaDemo(id = "1002",name = "葡萄")
    private String fruit2;
    public static void demo1(){
        Class<?> a = TestRepeatable.class;
        Field[] fruits = a.getDeclaredFields();
        Arrays.stream(fruits).forEach(f->{
            if(f.isAnnotationPresent(RepeaDemo.class)){
                RepeaDemo anno = f.getAnnotation(RepeaDemo.class);
                String id = anno.id();
                String name = anno.name();
                System.out.printf("水果id:%s,水果名稱:%s%n",id,name);
            }
        });
    }
    public static void demo2(){
        Class<?> a = TestRepeatable.class;
        Field[] fruits = a.getDeclaredFields();
        Arrays.stream(fruits).forEach(f->{
            if(f.isAnnotationPresent(RepeaDemos.class)){
                RepeaDemos anno = f.getAnnotation(RepeaDemos.class);
                RepeaDemo[] res= anno.value();
                Arrays.stream(res).forEach(r-> System.out.printf("水果id:%s,水果名稱:%s%n",r.id(),r.name()));
            }
            if(f.isAnnotationPresent(RepeaDemo.class)){
                RepeaDemo anno = f.getAnnotation(RepeaDemo.class);
                String id = anno.id();
                String name = anno.name();
                System.out.printf("水果id:%s,水果名稱:%s%n",id,name);
            }
        });
    }
    public static void main(String[] args) {
        demo2();
    }
}

執(zhí)行效果如下:

水果id:1001,水果名稱:荔枝
水果id:1003,水果名稱:沃柑
水果id:1002,水果名稱:葡萄

可見,如下兩種方式,獲取的結(jié)果是一致的,其實@Repeatable注解就是一種語法糖(類似于python的裝飾器語法糖等等),本質(zhì)上在java編譯時,使用如下的第2種注解方式,等同于使用第1種:

//1:
@RepeaDemos(value = {
    @RepeaDemo(id = "1001",name = "荔枝"),
    @RepeaDemo(id = "1003",name = "沃柑")
})
//2:
@RepeaDemo(id = "1001",name = "荔枝")
@RepeaDemo(id = "1003",name = "沃柑")

2.3 小結(jié)

1 @Repeatable注解使用前,需先增加一個注解的屬性值為子注解數(shù)組,且名稱為value()的父注解;

2 @Repeatable注解需要在子注解上標注,且@Repeatable注解的值為父注解class;

3 @Repeatable注解本質(zhì)上是一種語法糖。

到此這篇關于Java的@Repeatable注解使用詳細解析的文章就介紹到這了,更多相關@Repeatable注解的使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • spring cloud gateway使用 uri: lb://方式配置時,服務名的特殊要求

    spring cloud gateway使用 uri: lb://方式配置時,服務名的特殊要求

    這篇文章主要介紹了spring cloud gateway使用 uri: lb://方式配置時,服務名的特殊要求,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-12-12
  • 將字符串數(shù)字格式化為樣式1,000,000,000的方法

    將字符串數(shù)字格式化為樣式1,000,000,000的方法

    這篇文章主要介紹了將字符串數(shù)字格式化為樣式1,000,000,000的方法,有需要的朋友可以參考一下
    2014-01-01
  • Java實現(xiàn)壓縮 PDF文件大小的示例代碼

    Java實現(xiàn)壓縮 PDF文件大小的示例代碼

    在日常工作中,我們經(jīng)常會遇到 PDF 文件體積過大的問題,本文將為你揭示如何利用 Spire.PDF for Java 輕松實現(xiàn) PDF 文件大小的優(yōu)化與壓縮,感興趣的可以了解下
    2025-09-09
  • Java中線程Thread的特點及使用

    Java中線程Thread的特點及使用

    這篇文章主要介紹了Java中線程的特點及使用,線程是進程的組成部分,一個進程可以擁有多個線程,而一個線程必須擁有一個父進程,那么線程該如何使用,讓我們一起來看看吧
    2023-04-04
  • springboot實現(xiàn)攔截器的3種方式及異步執(zhí)行的思考

    springboot實現(xiàn)攔截器的3種方式及異步執(zhí)行的思考

    實際項目中,我們經(jīng)常需要輸出請求參數(shù),響應結(jié)果,方法耗時,統(tǒng)一的權限校驗等。本文首先為大家介紹 HTTP 請求中三種常見的攔截實現(xiàn),并且比較一下其中的差異。感興趣的可以了解一下
    2021-07-07
  • springboot整合mqtt客戶端示例分享

    springboot整合mqtt客戶端示例分享

    這篇文章主要介紹了springboot整合mqtt客戶端示例分享的相關資料,需要的朋友可以參考下
    2023-07-07
  • java實現(xiàn)文件上傳的詳細步驟

    java實現(xiàn)文件上傳的詳細步驟

    文件上傳是用戶將本地文件通過Web頁面提交到服務器的過程,涉及客戶端、服務器端、上傳表單等組件,在SpringBoot中,通過MultipartFile接口處理上傳文件,并將其保存在服務器,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • Java設計模式之觀察者模式詳解

    Java設計模式之觀察者模式詳解

    這篇文章主要介紹了Java設計模式之觀察者模式詳解,對象之間的多對一依賴的一種設計方案,被依賴的對象為Subject,依賴的對象為Observer,Subject通知Observer變化,需要的朋友可以參考下
    2023-12-12
  • 深入Java萬物之母Object類詳情

    深入Java萬物之母Object類詳情

    這篇文章主要介紹了Java萬物之母Object類詳情,Object類,它是所有類的默認父類 ,子類不用使用extends關鍵字繼承它,不管是JDK中的類,還是自定義的類
    2022-06-06
  • Java下SpringBoot創(chuàng)建定時任務詳解

    Java下SpringBoot創(chuàng)建定時任務詳解

    這篇文章主要介紹了Java下SpringBoot創(chuàng)建定時任務詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07

最新評論

昌都县| 娄烦县| 新巴尔虎左旗| 农安县| 社旗县| 牟定县| 营口市| 辉县市| 诸暨市| 西充县| 金秀| 长沙市| 永春县| 曲靖市| 手机| 辉南县| 旬阳县| 丰顺县| 涟源市| 北票市| 九龙坡区| 永春县| 全南县| 滦南县| 霍邱县| 天镇县| 中山市| 麻栗坡县| 尚义县| 湘阴县| 凉城县| 常宁市| 红桥区| 信丰县| 建始县| 青田县| 外汇| 子长县| 宁南县| 蓬莱市| 明溪县|