kucci / guava-libraries

Automatically exported from code.google.com/p/guava-libraries
Apache License 2.0
0 stars 0 forks source link

Suggestion: Serializable function interface #434

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
I've had some problems where I wanted to define a function and have it be 
serializable, this is the solution I came up with:

/**
 * @author Bjørn Soldal
 * @created 28. sep. 2010
 */
public interface SerializableFunction<F extends Serializable, T extends 
Serializable> extends Function<F, T>, Serializable {
}

Original issue reported on code.google.com by Bjorn.So...@gmail.com on 28 Sep 2010 at 10:08

GoogleCodeExporter commented 9 years ago
We usually make serializable functions like this:

  private enum MyFunction implements Function<Foo, Bar> {
    MyFunction;

    public Bar apply(Foo foo) { ... }
  }

I don't see a big need for your interface (btw, it really mustn't require F and 
T to extend Serializable).

Original comment by kevinb@google.com on 28 Sep 2010 at 1:59

GoogleCodeExporter commented 9 years ago
As far as I'm aware using an enum won't let you on-the-fly create a function 
which can be serialized. Just a brief example of how we have used Function in 
the past;

        private Function<Input, Output> buildWorkingFunction(final List<Worker> workers, final Integer metric1, final Integer metric2) {
            return new Function<Input, Output>() {

                public Output apply(Input from) {
                    /** Perform operation using workers and metrics provided at run time. */
                    return new Output();
                }
            };
        }

If you wanted to issue this command several times and get several functions out 
which you could then serialize for later use or were part of a larger 
serializable object.

I know that you don't need to specify that F & T extend serializable but I 
added that simply to force the use of serializable entities and in part to 
further convey the idea of the serializable contract.

Original comment by Bjorn.So...@gmail.com on 29 Sep 2010 at 7:58

GoogleCodeExporter commented 9 years ago
I'm not saying you don't *need* to require that F and T extend Serializable, 
I'm saying that you really need *not* to require that. For example, many Lists 
are serializable, but List does not 

Serializable is a runtime marker only; it is not useful as an actual *type.*

So your suggestion amounts to simply an interface whose purpose is to extend 
two other interfaces... the only purpose of this I can imagine is to enable you 
to implement two interfaces with a single *anonymous* class, as in your example.

But, serializing an anonymous class is a very bad idea!  Consider that simply 
rearranging your code a bit can render previously serialized objects suddenly 
unreadable, as the name of your class is suddenly MyOuterClass$8 instead of 
MyOuterClass$7.  And it gets worse.  From the Java serialization spec:

"Serialization of inner classes (i.e., nested classes that are not static 
member classes), including local and anonymous classes, is strongly discouraged 
for several reasons. Because inner classes declared in non-static contexts 
contain implicit non-transient references to enclosing class instances, 
serializing such an inner class instance will result in serialization of its 
associated outer class instance as well. Synthetic fields generated by javac 
(or other JavaTM compilers) to implement inner classes are implementation 
dependent and may vary between compilers; differences in such fields can 
disrupt compatibility as well as result in conflicting default serialVersionUID 
values. The names assigned to local and anonymous inner classes are also 
implementation dependent and may differ between compilers. Since inner classes 
cannot declare static members other than compile-time constant fields, they 
cannot use the serialPersistentFields mechanism to designate serializable 
fields. Finally, because inner classes associated with outer instances do not 
have zero-argument constructors (constructors of such inner classes implicitly 
accept the enclosing instance as a prepended parameter), they cannot implement 
Externalizable. None of the issues listed above, however, apply to static 
member classes."

http://download.oracle.com/javase/6/docs/platform/serialization/spec/serial-arch
.html#4539

Conclusion: there's little value in the interface described.

Original comment by kevinb@google.com on 5 Nov 2010 at 6:44

GoogleCodeExporter commented 9 years ago
"But, serializing an anonymous class is a very bad idea!  Consider that simply 
rearranging your code a bit can render previously serialized objects suddenly 
unreadable, as the name of your class is suddenly MyOuterClass$8 instead of 
MyOuterClass$7."

I agree with this, I guess a little context is needed to understand why I 
requested this. I work predominantly with Apache Wicket these days and Wicket 
serializes religiously. It throws a hissy fit whenever it encounters something 
which is not serializable. 

I figure other people will need this sort of interface too some time in the 
future but I recognize that perhaps it is a bit of an edge case and shouldn't 
go into Guava after all. Thank you for your time :)

Original comment by Bjorn.So...@gmail.com on 7 Nov 2010 at 6:43

GoogleCodeExporter commented 9 years ago
This issue has been migrated to GitHub.

It can be found at https://github.com/google/guava/issues/<id>

Original comment by cgdecker@google.com on 1 Nov 2014 at 4:15

GoogleCodeExporter commented 9 years ago

Original comment by cgdecker@google.com on 3 Nov 2014 at 9:09