英文:
Extending Generic Interface for generic validation
问题
I have been playing with the validation pattern from this blog post. Everything works out as expected but I am unable to add generics. Namely,
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);
}
}
However, when I try to make the Validator
interface generic
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);
}
}
I get a compilation error:
Validatior.this cannot be referenced from the static context.
I can't understand why. What am I doing wrong?
英文:
I have been playing with the validation pattern from this blog post. Everything works out as expected but I am unable to add generics. Namely,
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);
}
}
However, when I try to make the Validator
interface generic
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);
}
}
I get a compilation error:
> Validatior.this cannot be referenced from the static context.
I can't understand why. What am I doing wrong?
答案1
得分: 1
以下是要翻译的内容:
"我不明白为什么。我做错了什么吗?"
你做错的地方是在静态上下文中引用了类型参数。JLS规范说这是不允许的。
在以下情况下引用泛型类C的类型参数都会导致编译时错误:
- C内的任何类型声明的静态成员声明。
- C的静态初始化器 (§8.7),或
- C内的任何类声明的静态初始化器。
要使您的代码编译,一种方法是将其更改为如下所示:
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);
}
}
英文:
> „…I can't understand why. What am I doing wrong?…“
What you're doing wrong is referring to the type parameter in a static context. The JLS says that's not allowed…
> It is a compile-time error to refer to a type parameter of a generic class C in any of the following:
>
> - the declaration of a static member of C (§8.3.1.1, §8.4.3.2, §8.5.1).
>
> - the declaration of a static member of any type declaration nested within C.
>
> - a static initializer of C (§8.7), or
>
> - a static initializer of any class declaration nested within C.
One way to make your code compile is to change it to this…
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);
}
}
答案2
得分: 0
My first answer assumes you want nothing more than for the original code you posted to compile; with the fewest changes made to it. So that answer addresses only that assumption.
这个回答假定您只希望原始代码能够编译,而对其进行的更改最少。因此,这个回答仅仅解决了这个前提。
This is a different answer because it makes a different assumption; and requires more than one code change.
这是一个不同的回答,因为它基于不同的假设,并需要进行多个代码更改。
Assumption: You absolutely must have a static method?
假设:您绝对必须拥有一个静态方法?
You could get that with the following refactors:
您可以通过以下的重构来实现:
-
Introduce a
Validatible
interface… -
引入一个
Validatible
接口…
public interface Validatible{
boolean isValid();
}
-
Make
User
aValidatiable
… -
将
User
类实现Validatiable
接口…
public class User implements Validatible{
...
@Override
public boolean isValid(){
...
}
...
}
-
Simplify
Validator
… -
简化
Validator
…
public interface Validator {
ValidationResult validate(Validatible input);
}
-
Move your must-have
static
method to a utility/helper class… -
将您必须拥有的
static
方法移动到一个实用程序/辅助类中…
public class DeduperAnswer {
static Validator validate(Predicate<Validatible> tester, String error) {
return user ->
tester.test(user) ? ValidationResult.valid() :
ValidationResult.invalid(error);
}
...
}
You could then call DeduperAnswer.validate()
like I do in this demo…
然后,您可以调用 DeduperAnswer.validate()
就像我在这个演示中所做的一样…
Validator butWhatThen = DeduperAnswer.validate((user) -> { return user.isValid(); }, "not valid");
But like I asked in the comments, after you get back that Validator
from the static
method call, what do you intend to do with it then?
但是,就像我在评论中所问的,当您从 static
方法调用中获取了 Validator
后,您打算接下来如何使用它呢?
I've made the assumptions I've made because it's not 100% clear what your exact use case is. It would be super helpful if you would share that.
我做出了我的假设,因为您的确切用例不是百分之百清晰。如果您能分享一下,那将非常有帮助。
英文:
My first answer assumes you want nothing more than for the original code you posted to compile; with the fewest changes made to it. So that answer addresses only that assumption.
This is a different answer because it makes a different assumption; and requires more than one code change.
Assumption: You absolutely must have a static method?
You could get that with the following refactors:
-
Introduce a
Validatible
interface…public interface Validatible{ boolean isValid(); }
-
Make
User
aValidatiable
…public class User implements Validatible{ ... @Override public boolean isValid(){ ... } ... }
-
Simplify
Validator
…public interface Validator { ValidationResult validate(Validatible input); }
-
Move your must-have
static
method to a utility/helper class…public class DeduperAnswer { static Validator validate(Predicate<Validatible> tester, String error) { return user -> tester.test(user) ? ValidationResult.valid() : ValidationResult.invalid(error); } ... }
You could then call DeduperAnswer.validate()
like I do in this demo…
Validator butWhatThen = DeduperAnswer.validate((user) -> { return user.isValid(); }, "not valid");
But like I asked in the comments, after you get back that Validator
from the static
method call, what do you intend to do with it then?
I've made the assumptions I've made because it's not 100% clear what your exact use case is. It would be super helpful if you would share that.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论