一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java中Validated、Valid 、Validator區別詳解

Java中Validated、Valid 、Validator區別詳解

2021-12-03 13:33琦彥 Java教程

本文主要介紹了Java中Validated、Valid 、Validator區別,有時候面試的時候會被問到,他們的區別你知道幾個,本文就來詳細的介紹一下

1. 結論先出

Valid VS Validated 相同點
都可以對方法和參數進行校驗
@Valid和@Validated
兩種注釋都會導致應用標準Bean驗證。

如果驗證不通過會拋出BindException異常,并變成400(BAD_REQUEST)響應;或者可以通過Errors或BindingResult參數在控制器內本地處理驗證錯誤。另外,如果參數前有@RequestBody注解,驗證錯誤會拋出MethodArgumentNotValidException異常。

JSR 380

JSR 380 是用于 bean 驗證的 Java API 規范,是 Jakarta EE 和 JavaSE 的一部分。這確保 bean 的屬性滿足特定條件,使用諸如@NotNull、@Min和@Max 之類的注釋。

此版本需要 Java 8 或更高版本,并利用 Java 8 中添加的新功能,例如類型注釋和對Optional和LocalDate等新類型的支持。

有關規范的完整信息,請繼續閱讀JSR 380。

Valid VS Validated 不同點?

javax.validation.Valid

  • 是JSR-303規范標準注解支持,是一個標記注解。
  • 注解支持ElementType#METHOD,ElementType#FIELD, ElementType#CONSTRUCTOR,
  • ElementType#PARAMETER, ElementType#TYPE_USE

org.springframework.validation.annotation.Validated

  • 是Spring 做得一個自定義注解,增強了分組功能。
  • 注解支持 ElementType#TYPE,ElementType#METHOD,ElementType#PARAMETER

@Valid和@Validated區別

 

區別 @Valid @Validated
提供者 JSR-303規范 Spring
是否支持分組 不支持 支持
標注位置 METHOD, FIELD, CONSTRUCTOR, PARAMETER, TYPE_USE TYPE, METHOD, PARAMETER
嵌套校驗 支持 不支持

 

Validator

Bean Validation 2.0(JSR 380)定義了用于實體和方法驗證的元數據模型和API,Hibernate Validator是目前最好的實現

Validator接口有三個方法,可用于驗證整個實體或僅驗證實體的單個屬性

  • Validator#validate() 驗證所有bean的所有約束
  • Validator#validateProperty() 驗證單個屬性
  • Validator#validateValue() 檢查給定類的單個屬性是否可以成功驗證

不管是requestBody參數校驗還是方法級別的校驗,最終都是調用Hibernate Validator執行校驗,Spring Validation只是做了一層封裝。

驗證用戶的輸入是我們大多數應用程序中的常見功能。在 Java 生態系統中,我們專門使用Java Standard Bean Validation API來支持這一點。此外,從 4.0 版本開始,這也與 Spring 很好地集成在一起.

在接下來的部分中,讓我們詳細了解它們。

2. @Valid和???????@Validated 注解

在 Spring 中,我們使用 JSR-303 的@Valid注釋進行方法級別驗證。此外,我們還使用它來標記成員屬性以進行驗證。但是,此注釋不支持組驗證

組有助于限制驗證期間應用的約束。一個特殊的用例是 UI 界面(UI wizards)。在這里,在第一步中,我們可能有某個字段子組。在后續步驟中,可能有另一個組屬于同一個 bean。因此我們需要在每一步中對這些有限的字段應用約束,但@Valid不支持這一點。

在這種情況下,對于組級別,我們必須使用 Spring 的@Validated,它是 JSR-303 的@Valid的變體。這是在方法級別使用的。對于標記成員屬性,我們繼續使用@Valid注釋。

現在,讓我們直接進入并通過一個例子來看看這些注解的用法。

3. 例子

讓我們考慮一個使用 Spring Boot 開發的簡單用戶注冊。首先,我們將只有名稱和密碼屬性:

?
1
2
3
4
5
6
7
8
9
10
11
public class UserAccount {
 
    @NotNull
    @Size(min = 4, max = 15)
    private String password;
 
    @NotBlank
    private String name;
 
    // standard constructors / setters / getters / toString  
}

接下來,讓我們看看控制器。在這里,我們將使用帶有@Valid注釋的saveBasicInfo方法來驗證用戶輸入:

?
1
2
3
4
5
6
7
8
9
10
@RequestMapping(value = "/saveBasicInfo", method = RequestMethod.POST)
public String saveBasicInfo(
  @Valid @ModelAttribute("useraccount") UserAccount useraccount,
  BindingResult result,
  ModelMap model) {
    if (result.hasErrors()) {
        return "error";
    }
    return "success";
}

現在讓我們測試這個方法:

?
1
2
3
4
5
6
7
8
9
10
@Test
public void givenSaveBasicInfo_whenCorrectInput_thenSuccess() throws Exception {
    this.mockMvc.perform(MockMvcRequestBuilders.post("/saveBasicInfo")
      .accept(MediaType.TEXT_HTML)
      .param("name", "test123")
      .param("password", "pass"))
      .andExpect(view().name("success"))
      .andExpect(status().isOk())
      .andDo(print());
}

確認測試運行成功后,我們現在擴展功能。下一個合乎邏輯的步驟是將其轉換為復雜用戶注冊。第一步,名稱和密碼保持不變。在第二步中,我們將獲取諸如年齡 和 電話之類的附加信息。因此,我們將使用這些附加字段更新我們的域對象: 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class UserAccount {
    
    @NotNull
    @Size(min = 4, max = 15)
    private String password;
 
    @NotBlank
    private String name;
 
    @Min(value = 18, message = "Age should not be less than 18")
    private int age;
 
    @NotBlank
    private String phone;
    
    // standard constructors / setters / getters / toString  
}

但是,這一次我們會注意到之前的測試失敗了。這是因為我們沒有傳入age和phone字段。為了支持這種行為,我們需要組驗證和@Validated注釋。

為此,我們需要對字段進行分組,創建兩個不同的組。首先,我們需要創建兩個標記接口。每個組或每個步驟單獨一個。我們可以參考我們關于組驗證的文章以了解具體的實現方式。在這里,讓我們關注注釋的差異。

我們將有第一步的BasicInfo接口和第二步的 AdvanceInfo  。此外,我們將更新UserAccount類以使用這些標記接口,如下所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class UserAccount {
    
    @NotNull(groups = BasicInfo.class)
    @Size(min = 4, max = 15, groups = BasicInfo.class)
    private String password;
 
    @NotBlank(groups = BasicInfo.class)
    private String name;
 
    @Min(value = 18, message = "Age should not be less than 18", groups = AdvanceInfo.class)
    private int age;
 
    @NotBlank(groups = AdvanceInfo.class)
    private String phone;
    
    // standard constructors / setters / getters / toString  
    
}

此外,我們現在將更新我們的控制器以使用@Validated批注而不是@Valid:

?
1
2
3
4
5
6
7
8
9
10
@RequestMapping(value = "/saveBasicInfoStep1", method = RequestMethod.POST)
public String saveBasicInfoStep1(
  @Validated(BasicInfo.class)
  @ModelAttribute("useraccount") UserAccount useraccount,
  BindingResult result, ModelMap model) {
    if (result.hasErrors()) {
        return "error";
    }
    return "success";
}

由于此更新,我們的測試現在成功運行。現在讓我們也測試一下這個新方法:

?
1
2
3
4
5
6
7
8
9
10
@Test
public void givenSaveBasicInfoStep1_whenCorrectInput_thenSuccess() throws Exception {
    this.mockMvc.perform(MockMvcRequestBuilders.post("/saveBasicInfoStep1")
      .accept(MediaType.TEXT_HTML)
      .param("name", "test123")
      .param("password", "pass"))
      .andExpect(view().name("success"))
      .andExpect(status().isOk())
      .andDo(print());
}

這也運行成功。因此,我們可以看到@Validated的使用 對于組驗證至關重要。

接下來,讓我們看看@Valid如何觸發嵌套屬性的驗證。

4.使用@Valid嵌套校驗

@Valid注釋用于校驗嵌套屬性。這會觸發嵌套對象的驗證。例如,在我們當前的場景中,讓我們創建一個 UserAddress 對象:

?
1
2
3
4
5
6
7
public class UserAddress {
 
    @NotBlank
    private String countryCode;
 
    // standard constructors / setters / getters / toString
}

為了確保此嵌套對象的驗證,我們將使用@Valid注釋來裝飾該屬性:

?
1
2
3
4
5
6
7
8
9
10
public class UserAccount {
    
    //...
    
    @Valid
    @NotNull(groups = AdvanceInfo.class)
    private UserAddress useraddress;
    
    // standard constructors / setters / getters / toString
}

5. 組合使用@Valid和@Validated 進行集合校驗

如果請求體直接傳遞了json數組給后臺,并希望對數組中的每一項都進行參數校驗。此時,如果我們直接使用java.util.Collection下的list或者set來接收數據,參數校驗并不會生效!我們可以使用自定義list集合來接收參數:

包裝List類型,并聲明@Valid注解??????????????

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package com.devicemag.core.BO;
 
import javax.validation.Valid;
import java.util.*;
 
/**
 * @Title: 參數校驗工具類, 用于校驗List<E> 類型的請求參數
 * @ClassName: com.devicemag.core.BO.ValidList.java
 * @Description:
 *
 * @Copyright 2020-2021 - Powered By 研發中心
 * @author: 王延飛
 * @date: 2020/12/25 20:23
 * @version V1.0
 */
public class ValidList<E> implements List<E> {
 
    @Valid
    private List<E> list = new ArrayList<>();
 
    @Override
    public int size() {
        return list.size();
    }
 
    @Override
    public boolean isEmpty() {
        return list.isEmpty();
    }
 
    @Override
    public boolean contains(Object o) {
        return list.contains(o);
    }
 
    @Override
    public Iterator<E> iterator() {
        return list.iterator();
    }
 
    @Override
    public Object[] toArray() {
        return list.toArray();
    }
 
    @Override
    public <T> T[] toArray(T[] a) {
        return list.toArray(a);
    }
 
    @Override
    public boolean add(E e) {
        return list.add(e);
    }
 
    @Override
    public boolean remove(Object o) {
        return list.remove(o);
    }
 
    @Override
    public boolean containsAll(Collection<?> c) {
        return list.containsAll(c);
    }
 
    @Override
    public boolean addAll(Collection<? extends E> c) {
        return list.addAll(c);
    }
 
    @Override
    public boolean addAll(int index, Collection<? extends E> c) {
        return list.addAll(index, c);
    }
 
    @Override
    public boolean removeAll(Collection<?> c) {
        return list.removeAll(c);
    }
 
    @Override
    public boolean retainAll(Collection<?> c) {
        return list.retainAll(c);
    }
 
    @Override
    public void clear() {
        list.clear();
    }
 
    @Override
    public E get(int index) {
        return list.get(index);
    }
 
    @Override
    public E set(int index, E element) {
        return list.set(index, element);
    }
 
    @Override
    public void add(int index, E element) {
        list.add(index, element);
    }
 
    @Override
    public E remove(int index) {
        return list.remove(index);
    }
 
    @Override
    public int indexOf(Object o) {
        return list.indexOf(o);
    }
 
    @Override
    public int lastIndexOf(Object o) {
        return list.lastIndexOf(o);
    }
 
    @Override
    public ListIterator<E> listIterator() {
        return list.listIterator();
    }
 
    @Override
    public ListIterator<E> listIterator(int index) {
        return list.listIterator(index);
    }
 
    @Override
    public List<E> subList(int fromIndex, int toIndex) {
        return list.subList(fromIndex, toIndex);
    }
 
    public List<E> getList() {
        return list;
    }
 
    public void setList(List<E> list) {
        this.list = list;
    }
     // 一定要記得重寫toString方法
 
    @Override
    public String toString() {
        return "ValidList{" +
                "list=" + list +
                '}';
    }
}

比如,我們需要一次性保存多個UserAccount 對象,Controller層的方法可以這么寫:???????

?
1
2
3
4
5
6
7
8
9
@PostMapping("/saveList")
 
public Result saveList(@RequestBody @Validated(UserAccount.class) ValidationList<UserAccount > userList) {
 
// 校驗通過,才會執行業務邏輯處理
 
return Result.ok();
 
}

6. 自定義校驗

validator-api-2.0的約束注解有22個,具體我們看下面表格

空與非空檢查

 

注解 支持Java類型 說明
@Null Object 為null
@NotNull Object 不為null
@NotBlank CharSequence 不為null,且必須有一個非空格字符
@NotEmpty CharSequence、Collection、Map、Array 不為null,且不為空(length/size>0)

 

Boolean值檢查

 

注解 支持Java類型 說明 備注
@AssertTrue boolean、Boolean 為true 為null有效
@AssertFalse boolean、Boolean 為false 為null有效

 

日期檢查

 

注解 支持Java類型 說明 備注
@Future Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 驗證日期為當前時間之后 為null有效
@FutureOrPresent Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 驗證日期為當前時間或之后 為null有效
@Past Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 驗證日期為當前時間之前 為null有效
@PastOrPresent Date、Calendar、Instant、LocalDate、LocalDateTime、LocalTime、MonthDay、OffsetDateTime、OffsetTime、Year、YearMonth、ZonedDateTime、HijrahDate、JapaneseDate、MinguoDate、ThaiBuddhistDate 驗證日期為當前時間或之前 為null有效

 

數值檢查

 

注解 支持Java類型 說明 備注
@Max BigDecimal、BigInteger,byte、short、int、long以及包裝類 小于或等于 為null有效
@Min BigDecimal、BigInteger,byte、short、int、long以及包裝類 大于或等于 為null有效
@DecimalMax BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包裝類 小于或等于 為null有效
@DecimalMin BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包裝類 大于或等于 為null有效
@Negative BigDecimal、BigInteger,byte、short、int、long、float、double以及包裝類 負數 為null有效,0無效
@NegativeOrZero BigDecimal、BigInteger,byte、short、int、long、float、double以及包裝類 負數或零 為null有效
@Positive BigDecimal、BigInteger,byte、short、int、long、float、double以及包裝類 正數 為null有效,0無效
@PositiveOrZero BigDecimal、BigInteger,byte、short、int、long、float、double以及包裝類 正數或零 為null有效
@Digits(integer = 3, fraction = 2) BigDecimal、BigInteger、CharSequence,byte、short、int、long以及包裝類 整數位數和小數位數上限 為null有效

 

其他

 

注解 支持Java類型 說明 備注
@Pattern CharSequence 匹配指定的正則表達式 為null有效
@Email CharSequence 郵箱地址 為null有效,默認正則 '.*'
@Size CharSequence、Collection、Map、Array 大小范圍(length/size>0) 為null有效

 

hibernate-validator擴展約束(部分)

注解 支持Java類型 說明
@Length String 字符串長度范圍
@Range 數值類型和String 指定范圍
@URL   URL地址驗證

 

自定義約束注解

除了以上提供的約束注解(大部分情況都是能夠滿足的),我們還可以根據自己的需求自定義自己的約束注解

定義自定義約束,有三個步驟

  • 創建約束注解
  • 實現一個驗證器
  • 定義默認的錯誤信息

那么下面就直接來定義一個簡單的驗證手機號碼的注解

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Documented
@Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
@Constraint(validatedBy = {MobileValidator.class})
@Retention(RUNTIME)
@Repeatable(Mobile.List.class)
public @interface Mobile {
 
    /**
     * 錯誤提示信息,可以寫死,也可以填寫國際化的key
     */
    String message() default "手機號碼不正確";
 
    Class<?>[] groups() default {};
    
    Class<? extends Payload>[] payload() default {};
 
    String regexp() default "^1([38][0-9]|4[579]|5[0-3,5-9]|6[6]|7[0135678]|9[89])\\d{8}$";
    @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE})
    @Retention(RUNTIME)
    @Documented
    @interface List {
        Mobile[] value();
    }
}

關于注解的配置這里不說了,自定義約束需要下面3個屬性

  • message 錯誤提示信息,可以寫死,也可以填寫國際化的key
  • groups 分組信息,允許指定此約束所屬的驗證組(下面會說到分組約束)
  • payload 有效負載,可以通過payload來標記一些需要特殊處理的操作

@Repeatable注解和List定義可以讓該注解在同一個位置重復多次,通常是不同的配置(比如不同的分組和消息)
@Constraint(validatedBy = {MobileValidator.class})該注解是指明我們的自定義約束的驗證器,那下面就看一下驗證器的寫法,需要實現javax.validation.ConstraintValidator接口

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MobileValidator implements ConstraintValidator<Mobile, String> {
 
    /**
     * 手機驗證規則
     */
    private Pattern pattern;
 
    @Override
    public void initialize(Mobile mobile) {
        pattern = Pattern.compile(mobile.regexp());
    }
 
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (value == null) {
            return true;
        }
 
        return pattern.matcher(value).matches();
    }
}

ConstraintValidator接口定義了在實現中設置的兩個類型參數。

  • 第一個指定要驗證的注解類(如Mobile),
  • 第二個指定驗證器可以處理的元素類型(如String);initialize()方法可以訪問約束注解的屬性值;isValid()方法用于驗證,返回true表示驗證通過

Bean驗證規范建議將空值視為有效。如果null不是元素的有效值,則應使用@NotNull 顯式注釋

到這里我們自定義的約束就寫好了,可以用個例子來測試一下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class MobileTest {
 
    public void setMobile(@Mobile String mobile){
        // to do
    }
 
    private static ExecutableValidator executableValidator;
 
    @BeforeAll
    public static void setUpValidator() {
        ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
        executableValidator = factory.getValidator().forExecutables();
    }
 
    @Test
    public void manufacturerIsNull() throws NoSuchMethodException {
        MobileTest mobileTest = new MobileTest();
 
        Method method = MobileTest.class.getMethod("setMobile", String.class);
        Object[] parameterValues = {"1111111"};
        Set<ConstraintViolation<MobileTest>> violations = executableValidator.validateParameters(
                mobileTest, method, parameterValues);
        violations.forEach(violation -> System.out.println(violation.getMessage()));
    }
}

手機號碼不正確

工作原理

@Validated的工作原理

方法級別參數校驗

在每個參數前面聲明約束注解,然后通過解析參數注解完成校驗,這就是方法級別的參數校驗。 這種方式可以用于任何的Spring Bean的方法上,一般來說,這種方式一般會采用AOP的Around增強完成 在Spring中,是通過以下步驟完成

  • MethodValidationPostProcessor在Bean的初始化完成之后,判斷是否要進行AOP代理(類是否被@Validated標記)
  • MethodValidationInterceptor攔截所有方法,執行校驗邏輯
  • 委派Validator執行參數校驗和返回值校驗,得到ConstraintViolation
  • 處理ConstraintViolation

結論

總之,對于任何基本驗證,我們將在方法調用中使用 JSR @Valid注釋。另一方面,對于任何組驗證,包括組序列,我們需要 在我們的方法調用中使用 Spring 的@Validated注釋。所述@Valid 還需要注釋來觸發嵌套屬性的驗證。

  • @Validated的原理本質還是AOP。在方法校驗上,利用AOP動態攔截方法,利用JSR303 Validator實現完成校驗。在Bean的屬性校驗上,則是基于Bean的生命周期,在其初始化前后完成校驗
  • Spring Validator本質實現還是JSR303 Validaotr,只是能讓其更好的適配Spring Context
  • @javax.validation.Valid是JSR303的核心標記注解,但是在Spring Framework中被@Validated取代,但是Spring Validator的實現可以支持兼容@javax.validation.Valid

例如,在MethodValidationPostProcessor提供了setValidatedAnnotationType方法,替換默認的@Validated

在Spring MVC中,RequestResponseBodyMethodProcessor對@RequestBody和@ResponseBody的校驗處理,就兼容了@javax.validation.Valid和@Validated

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
    @Override
    protected void validateIfApplicable(WebDataBinder binder, MethodParameter parameter) {
        Annotation[] annotations = parameter.getParameterAnnotations();
        for (Annotation ann : annotations) {
            Validated validatedAnn = AnnotationUtils.getAnnotation(ann, Validated.class);
            if (validatedAnn != null || ann.annotationType().getSimpleName().startsWith("Valid")) {
                Object hints = (validatedAnn != null ? validatedAnn.value() : AnnotationUtils.getValue(ann));
                Object[] validationHints = (hints instanceof Object[] ? (Object[]) hints : new Object[] {hints});
                binder.validate(validationHints);
                break;
            }
        }
    }
}

參考鏈接:

https://www.baeldung.com/spring-valid-vs-validated

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/validation/annotation/Validated.html

https://docs.oracle.com/javaee/7/api/javax/validation/Valid.html

https://docs.jboss.org/hibernate/beanvalidation/spec/2.0/api/javax/validation/Validator.html

https://reflectoring.io/bean-validation-with-spring-boot/

https://jcp.org/en/jsr/detail?id=380

https://www.baeldung.com/javax-validation

到此這篇關于Java中Validated、Valid 、Validator區別詳解的文章就介紹到這了,更多相關Validated、Valid 、Validator區別內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/fly910905/article/details/119850168

延伸 · 閱讀

精彩推薦
  • Java教程小米推送Java代碼

    小米推送Java代碼

    今天小編就為大家分享一篇關于小米推送Java代碼,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧...

    富貴穩中求8032021-07-12
  • Java教程Java8中Stream使用的一個注意事項

    Java8中Stream使用的一個注意事項

    最近在工作中發現了對于集合操作轉換的神器,java8新特性 stream,但在使用中遇到了一個非常重要的注意點,所以這篇文章主要給大家介紹了關于Java8中S...

    阿杜7482021-02-04
  • Java教程Java實現搶紅包功能

    Java實現搶紅包功能

    這篇文章主要為大家詳細介紹了Java實現搶紅包功能,采用多線程模擬多人同時搶紅包,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙...

    littleschemer13532021-05-16
  • Java教程20個非常實用的Java程序代碼片段

    20個非常實用的Java程序代碼片段

    這篇文章主要為大家分享了20個非常實用的Java程序片段,對java開發項目有所幫助,感興趣的小伙伴們可以參考一下 ...

    lijiao5352020-04-06
  • Java教程Java BufferWriter寫文件寫不進去或缺失數據的解決

    Java BufferWriter寫文件寫不進去或缺失數據的解決

    這篇文章主要介紹了Java BufferWriter寫文件寫不進去或缺失數據的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望...

    spcoder14552021-10-18
  • Java教程xml與Java對象的轉換詳解

    xml與Java對象的轉換詳解

    這篇文章主要介紹了xml與Java對象的轉換詳解的相關資料,需要的朋友可以參考下...

    Java教程網2942020-09-17
  • Java教程升級IDEA后Lombok不能使用的解決方法

    升級IDEA后Lombok不能使用的解決方法

    最近看到提示IDEA提示升級,尋思已經有好久沒有升過級了。升級完畢重啟之后,突然發現好多錯誤,本文就來介紹一下如何解決,感興趣的可以了解一下...

    程序猿DD9332021-10-08
  • Java教程Java使用SAX解析xml的示例

    Java使用SAX解析xml的示例

    這篇文章主要介紹了Java使用SAX解析xml的示例,幫助大家更好的理解和學習使用Java,感興趣的朋友可以了解下...

    大行者10067412021-08-30
主站蜘蛛池模板: 把女的下面扒开添视频 | 外国a级片 | ass亚洲熟妇毛茸茸pics | xxxxx性13一14| 黑帮少爷爱上我第8集在线观看 | 国产精品自在线拍 | 美女胸又大又黄又www小说 | 爆操 | 欧美xxoo做爰猛烈视频 | 色版网站| 欧美成人v视频免费看 | 色综合色狠狠天天综合色 | 帅小伙和警官同性3p | 国产免费一区二区 | 国产精品麻豆久久99 | 精品国产美女福利在线 | 国产51社区精品视频资源 | 国产成人精品第一区二区 | 99在线观看视频免费 | 亚洲色导航 | 成人高辣h视频一区二区在线观看 | 成年性生交大片免费看 | 波多野结衣同性系列698 | 大奶妈咪女教师 | 色婷婷精品 | 欧美日韩亚洲国内综合网俺 | 国产精品福利在线观看入口 | 亚洲精品精品一区 | 手机看片国产免费现在观看 | 99热久久这里只有精品23 | free极度另类性欧美 | 欧美大b | 国产精品国语自产拍在线观看 | 国产精品视频色拍拍 | 久久视热频国产这里只有精品23 | 校园肉文高h | 91在线免费播放 | a级在线看 | 亚洲aⅴ天堂 | 黄色大片免费网站 | 91欧洲在线视精品在亚洲 |