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