正如this answer 中所说,允许创建具有多个方法的接口仍然是功能接口,这是默认方法的目的之一。正如那里也提到的,您会在 Java API 本身中找到示例,例如 Comparator、Predicate 或 Function,具有 default 方法并有意成为函数式接口。
default 实现是否什么都不做并不重要,更重要的问题是,这个默认实现有多自然。只是为了使 lambdas 成为可能,这感觉像是一个杂物,还是确实是某些甚至大多数实现会以任何方式使用的东西(不管它们是如何实现的)?
不需要特殊的清理操作可能确实是一种常见情况,即使您遵循评论中的建议,让您的界面扩展AutoCloseable 并将方法命名为close 而不是end。请注意,同样,Stream 实现了AutoCloseable,其默认行为是对close() 不执行任何操作。您甚至可以按照该模式将清理操作指定为单独的Runnable,类似于Stream.onClose(Runnable):
public interface StringTransformer extends UnaryOperator<String>, AutoCloseable {
static StringTransformer transformer(Function<String,String> f) {
return f::apply;
}
String transform(String s);
@Override default String apply(String s) { return transform(s); }
@Override default void close() {}
default StringTransformer onClose(Runnable r) {
return new StringTransformer() {
@Override public String transform(String s) {
return StringTransformer.this.transform(s);
}
@Override public void close() {
try(StringTransformer.this) { r.run(); }
}
};
}
}
这允许通过onClose 注册清理操作,因此以下工作:
try(StringTransformer t =
StringTransformer.transformer(String::toUpperCase)
.onClose(()->System.out.println("close"))) {
System.out.println(t.apply("some text"));
}
分别
try(StringTransformer t = transformer(String::toUpperCase)
.onClose(()->System.out.println("close 1"))) {
System.out.println(t.apply("some text"));
}
如果您使用import static。如果您链接多个操作,例如
,它还可以确保安全关闭
try(StringTransformer t = transformer(String::toUpperCase)
.onClose(()->System.out.println("close 1"))
.onClose(()->{ throw new IllegalStateException(); })) {
System.out.println(t.apply("some text"));
}
或
try(StringTransformer t = transformer(String::toUpperCase)
.onClose(()->{ throw new IllegalStateException("outer fail"); })
.onClose(()->{ throw new IllegalStateException("inner fail"); })){
System.out.println(t.apply("some text"));
}
请注意,try(StringTransformer.this) { r.run(); } 是 Java 9 语法。对于 Java 8,您需要 try(StringTransformer toClose = StringTransformer.this) { r.run(); }。