java - 通用单例工厂

标签 java generics

在网上阅读时,我遇到了以下问题:

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;
}

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

我的问题是,为什么我们在这里需要一个通用的接口(interface)

只需以下内容就足够了:

public interface UnaryFunction
{
    Object apply(Object arg); //Object as return type and argument type, instead.
}

?这里有什么需要使用泛型?

而且,什么是通用单例工厂?它有什么用处?

谢谢。

最佳答案

通用单例工厂是您示例中的 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());
    }
}

或者为您要支持的每种类型单独实现:

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;
    }
};

给你一些丑陋冗长的剪切粘贴代码,每个类型都有不同的名称,你必须保持直截了当。但是因为您知道它是一个纯函数并且类型被删除,所以您可以只有一个实现 (ID_FUNC) 并让单例工厂 idFunction 返回它。

如果您有一个函数实现,您希望能够在其中指定不同的类型,并且该实现是无状态的,则可以使用它。

这个例子可能会更好,因为它只在函数调用返回的对象上调用 toString ,工厂没有任何好处。如果示例显示对返回的对象使用特定于类型的方法,那么好处可能会更加明显。

执行此操作时会出现未经检查的强制转换警告,但可以安全地抑制它(这是 Joshua Bloch 的建议)。

关于java - 通用单例工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23942528/

相关文章:

java - Java使用Arraylist进行选举

C# 从反射类型实例化泛型列表

c# - 约束与参数 - 强制收集作为参数的方式

java - 泛型类<?扩展编号> 说明

java - 字符串的值对象

java - 使用方法引用将 List 类型 <Integer> 转换为 String[] 数组

java - Spring Boot 无法 Autowiring @ConfigurationProperties

java - Java 中的按键阻塞映射

c# - 最佳实践 : creating a data access class

c# - 是否可以通用地实现这个接口(interface),以便它只能传递一个类型参数?