假设我有两个类(class)
class A{
int a;
int getA(){
return this.a;
}
}
和
class B extends A{
String b;
String getB(){
return this.b;
}
}
我想要一个枚举,包含所有可能的值和继承树的 getter(不要问,我只是想问)。
enum ValueGetters{
A("a", A::getA),
B("b", B::getB);
String parameterName;
Function parameterGetter;
}
我在为此类编写构造函数时遇到问题。
ValueGetters(String parameterName, Function parameterGetter){
this.parameterName = parameterName;
this.parameterGetter = parameterGetter;
}
返回 A 和 B 的错误 ( Error:(12, 14) java: incompatible types: invalid method reference
)。
ValueGetters(String parameterName, Function<?,?> parameterGetter)
也是同样的情况
对于 ValueGetters(String parameterName, Function<? extends A,?> parameterGetter)
这只会为 B 提供错误,如果我尝试使用 ValueGetters(String parameterName, Function<? extends B,?> parameterGetter)
重载构造函数我有新的错误,两种类型都具有相同类型的删除。
另一方面ValueGetters(String parameterName, Object parameterGetter)
返回错误说明 Object
不是 Function
.
我试图定义我自己的 @FunctionalInterface
但它给了我同样的错误,以及 @FunctionalInterface
的重载方法接受两个 A
和 B
显然不是一个选项(或不是一个明显的选项)。
如果有人能为我的问题提出解决方案,我将不胜感激。
编辑和解决方案
我知道它不完全是一个枚举,但它以相同的方式工作并提供我需要的功能:
- 返回 setter/getter
- Getter 是类型敏感的
- 解决方案不需要对原有类做任何改动
- 与界面配合良好
...现在,代码:
public class ValueGetter<T extends A, R> {
private String name;
private Function<A,R> getter;
private ValueGetter(String name, Function<A, R> getter){
this.name = name;
this.getter = getter;
}
private static <T extends A, R> ValueGetter create(String name, Function<T,R> valueGetter){
return new ValueGetter(name, valueGetter);
}
public static ValueGetter<A, Integer> AA = create("a", A::getA);
public static ValueGetter<B, Integer> BB = create("a", B::getB);
public Function<T, R> getGetter(){
return (Function<T, R>) this.getter;
}
}
有了这个实现
A a1 = new A(12345);
B b1 = new B(54321, "sdfghjk");
System.out.println(ValueGetter.AA.getGetter().apply(a1));
System.out.println(ValueGetter.AA.getGetter().apply(b1));
System.out.println(ValueGetter.BB.getGetter().apply(b1));
编译并运行,而行
System.out.println(ValueGetter.BB.getGetter().apply(a1));
给出编译错误 apply(B) in function cannot be applied to (A)
最佳答案
实现它的一个方法是使用每个类的单例实例:
class BB { // Renamed B to BB to make it work with enum
String b;
private static final BB instance = new BB();
public static BB getInstance() {
return instance;
}
public String getB(){
return this.b;
}
// Example usage with cast
public String getB(Object b) {
return ((BB) b).getB();
}
}
public enum ValueGetters{
B("b", BB.getInstance()::getB);
String parameterName;
Function parameterGetter;
ValueGetters(String parameterName, Function parameterGetter){
this.parameterName = parameterName;
this.parameterGetter = parameterGetter;
}
}
你可以这样使用它:
ValueGetters.B.getGetter().apply(b);
关于java - 函数枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44042571/