使用标识函数编写函数会导致类型不匹配

时间:2016-06-29 02:34:47

标签: java generics enums functional-programming

我有一个enum和一个为enum值制作自定义字符串转换函数的方法:

public enum MyEnum {
  DUMMY;
}

public <E extends Enum<E>> Function<E, String> stringify(String suffix) {
  return enumValue -> enumValue.name() + suffix;
}

我想使用该方法为我的特定枚举类型创建一个函数:

public void test() {
  Function<MyEnum, String> f = stringify("");
}

这有效,但我还需要我的函数对字符串进行一些后续处理。为了举例,我们假设后续处理只是身份功能:

public void test() {
  Function<MyEnum, String> f = stringify("").andThen(Function.identity());
}

现在我收到编译错误。 Eclipse(Neon)说:

  

类型不匹配:无法从Function<Enum<Enum<E>>,String>转换为Function<Test.MyEnum,String>

javac说:

error: incompatible types: no instance(s) of type variable(s) V,T#2 exist so that Function<E,V> conforms to Function<MyEnum,String>
        Function<MyEnum, String> f = stringify("").andThen(Function.identity());
                                                      ^
  where V,R,T#1,T#2,E are type-variables:
    V extends Object declared in method <V>andThen(Function<? super R,? extends V>)
    R extends Object declared in interface Function
    T#1 extends Object declared in interface Function
    T#2 extends Object declared in method <T#2>identity()
    E extends Enum<E>

Function.identity()的返回类型与其参数类型相同,因此我不知道它如何将整体结果更改为Function<MyEnum, String>以外的其他内容。我特别对Eclipse错误消息中的Enum<Enum<E>>感到困惑。

我注意到我可以通过将中间结果分配给变量来避免这个问题:

public void test() {
  Function<MyEnum, String> f1 = stringify("");
  Function<MyEnum, String> f2 = f1.andThen(Function.identity());
}

但是如果可能的话,我宁愿避免这种情况。

为什么会出现这种类型不匹配?解决问题的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

这是一个泛型问题。

在此声明中:

Function<MyEnum, String> f = stringify("").andThen(Function.identity());

编译器不知道stringify的界限(&#34;&#34;),因此也无法推断出Function.identity()的界限。

要解决此问题,您需要将绑定添加到stringify("")

Function<MyEnum, String> f = this.<MyEnum>stringify("").andThen(Function.identity());

请注意,我们也添加了this关键字,因为您不能简单地写<MyEnum>stringify("")

如果stringify("")方法来自某个静态util类,则它将如下所示:

Function<MyEnum, String> f = MyUtils.<MyEnum>stringify("").andThen(Function.identity());