【发布时间】:2015-06-28 21:27:03
【问题描述】:
是否可以声明一个以 Serializable lambda 作为参数的方法,而无需声明专用接口或要求客户端 cast the lambda ?
让我们用这个玩具例子来说明我的问题:
static <T, R> void serialize(Function<T, R> f) throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream())) {
oos.writeObject(f);
}
}
public static void main(String[] args) throws IOException {
serialize(e -> e);
}
默认情况下,Lambda 是不可序列化的,并且会抛出预期的 NotSerializableException。
为了让它工作,我们可以强制转换 lambda 以添加一个额外的 Serializable 绑定。
static <T, R> void serialize(Function<T, R> f) throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream())) {
oos.writeObject(f);
}
}
public static void main(String[] args) throws IOException {
serialize((Function<Object, Object> & Serializable) e -> e);
}
但是,这种解决方案令人不快,因为它强制每个调用者转换他们的 lambda,并且方法签名确实表明 f 必须是可序列化的。它冗长且容易出错。
要删除样板并使其类型安全,我们可以定义一个专用接口:
interface SerFunction<T, R> extends Function<T, R>, Serializable { }
static <T, R> void serialize(SerFunction<T, R> f) throws IOException {
try (ObjectOutputStream oos = new ObjectOutputStream(new ByteArrayOutputStream())) {
oos.writeObject(f);
}
}
public static void main(String[] args) throws IOException {
serialize(e -> e);
}
它完成了这项工作,几乎满足了我的需求。这种模式的唯一缺点是我必须在每个功能接口之上创建一个专用接口,这有点麻烦。是否可以使用额外的接口并直接在方法签名中声明多个边界?
【问题讨论】:
标签: java serialization lambda