Guava toStringFunction() 具有以下声明:
public static Function<Object, String> toStringFunction() { ... }
Object 的所有非原始根,因此该函数运行良好。
但是当我尝试将它与另一个函数组合时,例如:
Function<Integer, Double> f1 = Functions.compose(Functions.forMap(someMap),
Functions.toStringFunction());
其中 someMap 变量是一个 map
Function<Integer, Double> f1 = Functions.compose(Functions.forMap(someMap),
^
required: Function<Integer,Double>
found: Function<Object,Double>
2 errors
我的两个问题是:
1.如何明确告诉编译器toStringFunction应该是Function
Function< Integer, String> g1 = (Function< Integer, String>)Functions.toStringFunction();
// cause error
2.将toStringFunction写成如下:
@SuppressWarnings("unchecked")
public static <E> Function<E, String> toStringFunction(){
return (Function<E, String>) ToStringFunction.INSTANCE;
}
// enum singleton pattern
private enum ToStringFunction implements Function<Object, String>{
INSTANCE;
// @Override public String toString(){
// return "Functions.toStringFunction()";
// }
@Override public String apply(Object o){
return o.toString();
}
}
我可以指定类型:
Function<Integer, Double> f1 = Functions.compose(Functions.forMap(someMap),
Functions.<Integer>toStringFunction());
这很好用。但是 Guava 团队现在拥有的版本的动机是什么?
最佳答案
原因toStringFunction()
是 Function<Object, String>
而不是 Function<T, String>
很简单,因为您可以调用 toString()
在任何 Object
.它实际上是一个接受对象并返回字符串的函数。 Guava 避免将类型参数(和通配符泛型)引入无用的方法。
您示例中的问题是您正在尝试输入 f1
用作Function<Integer, Double>
当它实际上是一个 Function<Object, Double>
: 它可以带任何对象,请调用 toString()
在上面,将该字符串传递给您的 forMap
函数并得到结果。
此外,假设正确使用泛型,您的函数类型不应该是 Function<Integer, Double>
的任何实际必要性。而不是 Function<Object, Double>
, 因为大多数接受函数并使用它来做某事的代码应该接受类似 Function<? super F, ? extends T>
的东西.所以这里真正的问题是“为什么要将 Function<Object, Double>
称为 Function<Integer, Double>
”?
关于java - Guava 为什么 toStringFunction 不是泛型函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29134719/