在有效Java项目27中,Bloch提倡使用通用的单例工厂“来创建不可变但适用于许多不同类型的对象”。他的例子是:

interface UnaryFunction<T> {
    T apply(T t);
}

public class Example {
    private static UnaryFunction<Object> IDENTITY_FUNCTION = (k -> k);

    // [snip] detailed explanation of why this is safe...
    @SuppressWarnings("unchecked")
    public static <T> UnaryFunction<T> identityFunction() {
        return (UnaryFunction) IDENTITY_FUNCTION;
    }

    public static void main(String... args) {
        String[] strings = { "jute", "hemp", "nylon" };
        UnaryFunction<String> sameString = identityFunction();
        for (String s : strings) {
            System.out.println(sameString.apply(s));
        }
    }
}


这是OpenJDK实现身份功能的方式:

@FunctionalInterface
interface UnaryOperator<T> extends Function<T, T> {
    static <T> UnaryOperator<T> identity() {
        return t -> t;
    }
}


鉴于Java 8在接口上支持静态方法,泛型单例工厂是否还有用例?

最佳答案

接口和通用单例工厂中的默认方法彼此独立。

通用单例工厂是一种实现技术,它允许您通过应用我们的Java内部知识(特别是我们的类型擦除知识)在不同的上下文中重用同一对象,但是接口中的默认方法可让您“水平”共享实现。

您可以通过在默认方法实现中使用通用单例工厂来结合这两种技术:

@FunctionalInterface
interface UnaryOperator<T> extends Function<T, T> {
    static UnaryOperator<Object> IDENTITY_FUNCTION = (k -> k);
    static <T> UnaryOperator<T> identity() {
        return (UnaryOperator)IDENTITY_FUNCTION;
    }
}


Demo.

因此,您的问题的答案是“不,静态接口方法不能代替通用单例工厂”。

09-28 06:15