在网上阅读时,我遇到了以下问题:
public interface UnaryFunction<T>
{
T apply(T arg);
}
.......
private static UnaryFuntion<Object> ID_FUNC = new UnaryFunction<Object>
{
Object apply(Object arg)
{
return arg;
}
};
public static <T> UnaryFunction<T> idFunction()
{
return (UnaryFunction<T>) ID_FUNC;
}
Run Code Online (Sandbox Code Playgroud)
在main:
public static void main(String[] args)
{
String[] strings = {"Peter", "Paul", "Mary"};
UnaryFunction<String> names = idFunction();
for(String s : strings)
{
System.out.println(names.apply(s));
}
Number[] numbers = {1, 2.0, 3L};
UnaryFunction<Number> nums = idFunction();
for(Number n : numbers)
{
System.out.println(nums.apply(n));
}
}
Run Code Online (Sandbox Code Playgroud)
我的问题是,为什么我们interface这里需要泛型?
简单地满足以下条件即可:
public interface UnaryFunction
{
Object apply(Object arg); //Object as return type and argument type, instead.
}
Run Code Online (Sandbox Code Playgroud)
?这里需要使用泛型吗?
而且,实际上什么是通用单例工厂?到底有什么好处呢?
谢谢。
通用单例工厂是示例中的 idFunction。如果没有它,你将不得不在两个丑陋的替代方案之间进行选择,要么在任何使用它的地方都需要强制转换,如下所示:
public class ExampleWithoutGenericSingletonFactory {
static UnaryFunction<Object> ID_FUNC = new UnaryFunction<Object>() {
public Object apply(Object arg) {
return arg;
}
};
public static void main(String[] args) {
BigDecimal b = new BigDecimal("1234.1241234");
BigDecimal b1 = (BigDecimal)(ID_FUNC.apply(b)); // have to cast here >_<
System.out.println("engineeringstring val of b1 = "
+ b1.toEngineeringString());
}
}
Run Code Online (Sandbox Code Playgroud)
或者为您想要支持的每种类型进行单独的实现:
public static UnaryFunction<String> ID_FUNC_STRING = new UnaryFunction<String>() {
public String apply(String arg) {
return arg;
}
};
public static UnaryFunction<Number> ID_FUNC_NUM = new UnaryFunction<Number>() {
public Number apply(Number arg) {
return arg;
}
};
public static UnaryFunction<BigDecimal> ID_FUNC_DECIMAL = new UnaryFunction<BigDecimal>() {
public Number apply(BigDecimal arg) {
return arg;
}
};
Run Code Online (Sandbox Code Playgroud)
给你一些丑陋的冗长的剪切粘贴代码,对于你必须保持正确的每种类型都有不同的名称。但由于您知道它是一个纯函数并且类型会被删除,因此您只能有一个实现 (ID_FUNC) 并让单例工厂 idFunction 返回它。
您可以在以下情况下使用此功能:您希望能够在一个函数实现上指定不同的类型,并且该实现是无状态的。
该示例可能会更好,因为它仅对从函数调用返回的对象调用 toString,因此工厂没有显示出任何好处。如果示例显示对返回的对象使用特定于类型的方法,那么好处可能会更明显。
当您执行此操作时,会出现未经检查的强制转换警告,但可以安全地抑制它(这是 Joshua Bloch 的建议)。