在Effective Java Item 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支持接口上的静态方法,是否还有通用单例工厂的用例?
答案 0 :(得分:3)
接口和通用单件工厂中的默认方法是相互独立的。
虽然通用单件工厂是一种实现技术,它允许您通过应用我们的Java内部知识(特别是我们的类型擦除知识)在不同的上下文中重用相同的对象,接口中的默认方法可以让您共享实现和#34;水平&#34;
您可以在默认方法实现中使用通用单例工厂来组合这两种技术:
public class TheMage extends JFrame {
private static Player Ship = new Player(50,50);
...
@Override
public void keyPressed(KeyEvent ke) {
TheMage.Ship //blah blah blah
}
所以答案是你的问题&#34;不,静态接口方法不能取代通用的单件工厂&#34;。
答案 1 :(得分:1)
鉴于Java 8支持接口上的静态方法,是否还有通用单例工厂的用例?
您提供的UnaryOperator
示例无法保证提供单身人士。这是允许的,但不是必需的。
此外,如果您提供的代码确实提供了单例,那么它只是将通用单件工厂模式的实现作为静态接口方法。然后它可能证明是一种特别方便的实现,但它并不是一个不同的变化。
即使您认为静态接口方法接近另一种选择,它仍然只涵盖接口作者或维护者所考虑的情况。如果你想要一个不同的产品,那么使用传统形式的通用单件工厂仍然是有意义的,比如说:
public class Example {
private final static UnaryFunction<Object> LOG_FUNCTION =
(k -> { System.out.println(k); return k; });
@SuppressWarnings("unchecked")
public static <T> UnaryFunction<T> logFunction() {
return (UnaryFunction) LOG_FUNCTION;
}
public static void main(String... args) {
String[] strings = { "jute", "hemp", "nylon" };
UnaryFunction<String> logIt = logFunction();
for (String s : strings) {
logIt(s);
}
}
}