I’m looking for design rationale here.
I can understand making collection classes Serializable as a matter of course, although JCF doesn’t do that. Nevertheless, the Procedure
, IntProcedure
, etc. interfaces in particular are prime candidates for not being Serializable
since they will often be anonymous anyway.
Making those interfaces Serializable
goes against Josh Bloch’s advice that interfaces should rarely extend Serializable
[1].
I may need to update my Eclipse preferences not to emit serial uid warnings for every anonymous Procedure
.
[1] Effective Java 2nd Ed. pg 291
Advertisement
Answer
This question was asked quite a few years ago. I will explain the design rationale behind making all of the functional interfaces in Eclipse Collections extend Serializable
, as best as I can recall it. The decision was made over 15 years ago. Note: I am the creator of Eclipse Collections.
Eclipse Collections has been in development since 2004. It started out its development lifecycle in JDK 1.4. Eclipse Collections had functional interfaces and a functional API, ten years before there were lambdas and Streams available in Java 8. In order to use the functional API of Eclipse Collections with the functional interfaces before Java 8, we often had to create anonymous inner classes.
We had a need to serialize the functional interfaces between caches in a proprietary distributed caching architecture and also to occasionally serialize them to disk. Intersection types were added to the Java language in Java 8 to support serialization of lambdas. Prior to Java 8, we had to choose a single interface or class to implement an anonymous inner class. If a functional interface we used for an anonymous inner class was not Serializable
, we had no way to make it Serializable
without creating a named class that extended both the functional interface and Serializable
.
One possibility we considered would have been to have a parallel hierarchy of functional interfaces. We could have had a Function
interface, which did not extend Serializable
, and then add a second SerializableFunction
interface which would extend both Function
and Serializable
. There are some examples in the distributed caching space that took this approach of having parallel hierarchies. For instance Oracle Coherence and Hazelcast have functional interfaces which extend JDK equivalent interfaces and Serializable
. If we had done this in Eclipse Collections it would have resulted in doubling our total functional interface types (today around 500) to almost 1K functional interface types.
Ultimately, we decided the best approach for Eclipse Collections was to make all of our functional interfaces simply extend Serializable
.
After Java 8 was released, we added @FunctionalInterface
to our functional interfaces, and changed them to extend the equivalent functional interfaces in the JDK. This resulted in us having Serializable
versions of the JDK interfaces that we could use with Eclipse Collections and Java Streams APIs.
Here are links to all of the object and primitive functional interfaces included in Eclipse Collections. As can be seen, the functional interfaces are voluminous because of the support for a functional API on primitive collections.
When Project Valhalla is delivered and generics support for primitives is included in a LTS (Long Term Support) Java Release, we will eventually upgrade Eclipse Collections and possibly remove most of our current primitive functional interfaces as they will no longer be necessary. I say possibly, as this would be a breaking change resulting in a substantial amount of work and require a major release of Eclipse Collections. More importantly, it would impact all of the current clients.