Enum singleton versus non-capturing lambda
Brian Goetz
brian.goetz at oracle.com
Wed Mar 13 21:04:09 PDT 2013
The general guideline with serialized lambdas is that you basically get
the same level (or slightly better, but not much better) of
name-stability as you get with inner classes. Which is -- have the same
class files on both sides of the pipe, and no one gets hurt.
With inner classes, you have the problem of "stable method name,
unstable class name." With lambdas, its basically the dual; stable
class name, unstable method name. We've made some small attempts to
avoid gratuitous instability in the method name, but don't expect much
in the way of stability across recompilations. Whereas enums (and named
classes) promise much more in the way of stability.
On 3/13/2013 10:43 PM, Michael Hixson wrote:
> So if I'm in that situation where the serialized form has changed,
> what happens? Deserialization throws an error?
>
> I'm trying to convert this into general guideline I can use.
> Something like: "Only serialize lambdas into ephemeral storage. If
> you need persistent storage, use an enum instead." (?)
>
> On Wed, Mar 13, 2013 at 6:40 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
>> A more apt comparison would be the serialized form of a lambda. Which is
>> probably bigger.
>>
>> But, the name-stability is a huge benefit. While we've made some attempts
>> to make the serialized form of lambdas stable across compilations, there are
>> no guarantees. Enums provide those guarantees.
>>
>>
>> On 3/13/2013 8:51 PM, Zhong Yu wrote:
>>>
>>> On Wed, Mar 13, 2013 at 7:09 PM, Brian Goetz <brian.goetz at oracle.com>
>>> wrote:
>>>>
>>>> Free, compact, guaranteed-stable serialization format.
>>>
>>>
>>> It seems that the serialized format of the enum singleton is 40 bytes
>>> longer than a traditional singleton, if that's a concern to anyone.
>>>
>>>>
>>>>
>>>> On 3/13/2013 8:03 PM, Zhong Yu wrote:
>>>>>
>>>>>
>>>>> On Wed, Mar 13, 2013 at 4:51 PM, Michael Hixson
>>>>> <michael.hixson at gmail.com> wrote:
>>>>>>
>>>>>>
>>>>>> I see a couple of different forms for returning functional interface
>>>>>> instances from static methods in the current lambda code.
>>>>>>
>>>>>> 1. Enum singleton, as in Comparators.naturalOrder()
>>>>>>
>>>>>> private enum NaturalOrderComparator implements
>>>>>> Comparator<Comparable<Object>> {
>>>>>> INSTANCE;
>>>>>> public int compare(Comparable<Object> c1, Comparable<Object> c2)
>>>>>> {
>>>>>> return c1.compareTo(c2);
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> public static <T extends Comparable<? super T>> Comparator<T>
>>>>>> naturalOrder() {
>>>>>> return (Comparator<T>) NaturalOrderComparator.INSTANCE;
>>>>>> }
>>>>>>
>>>>>> 2. Non-capturing lambda, as in Functions.identity()
>>>>>>
>>>>>> public static <T> Function<T, T> identity() {
>>>>>> return t -> t;
>>>>>> }
>>>>>>
>>>>>> Code complexity aside, does either approach have advantages over the
>>>>>> other? Does one perform better/worse or serialize better/worse?
>>>>>
>>>>>
>>>>>
>>>>> I'd like to know too. What's the purpose of enum in the 1st example?
>>>>>
>>>>>>
>>>>>> -Michael
>>>>>>
>>>>>
>>>>
>>
More information about the lambda-dev
mailing list