我正在编写一个可序列化的类,它接受几个参数,包括一个函数:
public class Cls implements Serializable {
private final Collection _coll;
private final Function _func;
public Cls(Collection coll, Function func) {
_coll = coll;
_func = func;
}
}
func存储在成员变量中,因此需要可序列化. Java lambdas are serializable if the type they’re being assigned to is serializable.什么是最好的方法来确保我的构造函数中传递的函数是可序列化的,如果它是使用lambda创建的?
>创建一个SerializableFunction类型并使用它:
public interface SerializableFunction implements Function, Serializable {}
....
public Cls(Collection coll, SerializableFunction func) {...}
问题:
> coll和func参数之间现在不匹配,因为func在签名中被声明为可序列化,但是coll不是,但是都需要可序列化才能工作.
>它不允许Function的其他实现可序列化.
>在构造函数上使用一个类型参数:
public & Serializable>
Cls(Collection coll, F func) {...}
问题:
>比1更灵活,但更混乱.
>两个参数之间仍然存在不匹配 – func参数是在编译时类型的父进程中实现Serializable所必需的,但是coll只是需要以某种方式进行序列化(尽管如果需要可以将其删除).
编辑当尝试使用lambda或方法引用调用时,此代码实际上不会编译.
把它留给来电者
这需要调用者知道(从javadocs或者是试验和错误)参数需要是可序列化的,并且适当地转换:
Cls c = new Cls(strList, (Function & Serializable)s -> ...);
要么
Cls c = new Cls(strList, (Function & Serializable)Foo::processStr);
这是一个丑陋的IMO,并且使用lambda的初始天真的实现保证破坏,而不是像coll一样工作(因为大多数集合可以以某种方式串行化).这也将类的实现细节推送到调用者.
目前,我倾向于选项2,作为对呼叫者施加最小负担的那个,但是我不认为这里有一个理想的解决方案.任何其他建议如何正确地做到这一点?
编辑:也许需要一些背景.这是一个在storm中运行的类,它是一个螺栓,它被序列化以传送到删除集群来执行.该功能是在集群上运行时对已处理的元组执行操作.所以它是类的目的的很大一部分,它是可序列化的,并且函数参数是可序列化的.如果不是,则该类根本不可用.