将函数与恒等函数组合会导致类型不匹配



我有一个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>

and 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());
}

但如果可能的话,我宁愿避免。

为什么会出现这种类型不匹配?最好的解决办法是什么?

这是一个泛型边界问题。

在这个语句中:

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

编译器不知道stringify(")的边界,因此也不能推断出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());

相关内容

  • 没有找到相关文章

最新更新