簡體   English   中英

為通用驗證擴展通用接口

[英]Extending Generic Interface for generic validation

我一直在玩這篇博文中的驗證模式。 一切都按預期進行,但我無法添加 generics。 即,

public interface Validator extends Function<User, ValidationResult> {
    static Validator validate(Predicate<User> tester, String error) {
        return user -> 
            tester.test(user) ? ValidationResult.valid() : 
                    ValidationResult.invalid(error);
    }
}

但是,當我嘗試使Validator接口通用時

public interface Validator<T> extends Function<T, ValidationResult> {
    static Validator validate(Predicate<T> tester, String error) {
        return subject ->
                tester.test(subject) ? ValidationResult.valid() :
                        ValidationResult.invalid(error);
    }
}

我得到一個編譯錯誤:

Validatior.this 不能從 static 上下文中引用。

在此處輸入圖像描述

我不明白為什么。 我究竟做錯了什么?

“……我不明白為什么。 我究竟做錯了什么? ……”

您做錯了什么是指static上下文中的類型參數。 JLS 說這是不允許的……

在以下任一情況下引用通用 class C 的類型參數是編譯時錯誤

  • C ( §8.3.1.1 , §8.4.3.2 , §8.5.1 )的 static 成員的聲明

  • 嵌套在 C 中的任何類型聲明的 static 成員的聲明

  • C ( §8.7 )的 static 初始化程序

  • 嵌套在 C 中的任何 class 聲明的 static 初始化程序

使您的代碼編譯的一種方法是將其更改為...

public interface Validator<T> extends Function<T, ValidationResult> {
    
    default Validator validate(Predicate<T> tester, String error) {
        return user -> 
            tester.test((T)user) ? ValidationResult.valid() : 
                    ValidationResult.invalid(error);
    }
}

我的第一個答案假設您只需要發布要編譯的原始代碼; 對其進行最少的更改。 因此,該答案解決了該假設。

這是一個不同的答案,因為它做出了不同的假設; 並且需要不止一次的代碼更改。

假設你絕對必須有一個 static 方法?

您可以通過以下重構獲得它:

  • 引入一個Validatible接口……

     public interface Validatible{ boolean isValid(); }
  • 使User成為Validatiable的……

     public class User implements Validatible{... @Override public boolean isValid(){... }... }
  • 簡化Validator ……

     public interface Validator { ValidationResult validate(Validatible input); }
  • 將您必備的static方法移至實用程序/幫助程序類……

     public class DeduperAnswer { static Validator validate(Predicate<Validatible> tester, String error) { return user -> tester.test(user)? ValidationResult.valid(): ValidationResult.invalid(error); }... }

然后你可以像我在這個演示中那樣調用DeduperAnswer.validate() ......

    Validator butWhatThen = DeduperAnswer.validate((user) -> { return user.isValid(); }, "not valid");

但是就像我在評論中問的那樣,在您從static方法調用中取回該Validator之后,您打算如何處理它?

我已經做出了我所做的假設,因為它不是 100% 清楚你的確切用例是什么。 如果您願意分享,那將非常有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM