java - 函数枚举

标签 java enums functional-interface

假设我有两个类(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 的重载方法接受两个 AB显然不是一个选项(或不是一个明显的选项)。

如果有人能为我的问题提出解决方案,我将不胜感激。

编辑和解决方案

我知道它不完全是一个枚举,但它以相同的方式工作并提供我需要的功能:

  1. 返回 setter/getter
  2. Getter 是类型敏感的
  3. 解决方案不需要对原有类做任何改动
  4. 与界面配合良好

...现在,代码:

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/

相关文章:

java - 如何通过反射获取函数的java类型注释

Java 8 流,为什么要编译第 2 部分……或者什么是方法引用,真的吗?

JavaFX 防止 TableMenuButton 隐藏所有列

Java 枚举常量值不会改变

java - InjectMocks类的方法返回Null

c# - 在 C# 中,我应该使用 Enum、static Class、Dictionary 还是 Struct 来表示这些 "labeled floats"?

c - 值看起来是字符串的枚举类型是什么?

java - 消除 lambda 中函数接口(interface)的歧义

java - 在 java 中调用通用 protobuffer 类的 parseFrom() 方法

java - Websphere 应用程序服务器 [警告] CWWKC0044W 和 [警告] CWWKC0022W :