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