Serialization opt-in syntax (again)

Brian Goetz brian.goetz at oracle.com
Sat Sep 29 14:20:03 PDT 2012


Here is another option that we explored a while ago and initially turned our nose up at, but we are still willing to explore: using intersection types in a cast to target type, inspired by multiple type bounds in generics: 

    Predicate<String> ps = (Predicate<String> & Serializable) x-> x.isEmpty();

The major downsides are:
 - Verbose (have to repeat the target type)
 - Another ad-hoc context where we allow intersection types, though offers some runway in the event we want to extend the use of intersection types in the future.  

It extends to inner class expressions in an OK manner:

  new Foo(blah) & Serializable { ... }

Again, the cast syntax can apply to any intersection of types that meets the SAM-ness requirement, and the inner class syntax can be any arbitrary set of interfaces.  


On Sep 28, 2012, at 11:48 PM, Brian Goetz wrote:

> Bob is definitely right here that the semantics of this are closer to what we want than any of the others.  While the proximate problem is "how do I make a serializable lambda", the way you make a class serializable in Java is (in part) to extend Serializable.  So something that addresses the "how to I extend Serializable" question is much more in the spirit of how serialization works (for better or worse) than a special magic serialization syntax.  
> 
> 
> On Sep 28, 2012, at 4:14 PM, Bob Lee wrote:
> 
>> I like the semantics a lot! Maybe moving the "implements" decl to the right of the -> would address Kevin's concerns? Then it would read "lambda (->) implements ..."
>> 
>> Bob
>> 
>> On Fri, Sep 28, 2012 at 1:47 PM, Brian Goetz <brian.goetz at oracle.com> wrote:
>> I put all the candidate syntaxes so far in the JIRA issue for this, but a new one came to light this week that we kind of like.
>> 
>> The problem is: let's say you have a SAM that is not serializable, but you want the instance to be, such as in:
>> 
>>   Runnable r = () -> { };
>> 
>> The problem is that we really want to specify multiple interfaces for the lambda, and as long as their intersection has only one abstract method, that should be OK.
>> 
>> So, how about using the space between the closing paren and the arrow:
>> 
>>   Runnable r = () implements Serializable -> { ... }
>> 
>> As a bonus, if we wanted to be explicit about all the implemented interfaces, this easily extends to:
>> 
>>   Object p = (String s) implements Predicate<String>, Serializable -> { ... }
>> 
>> 
>> This also extends nicely to inner class creation expressions.  Right now there is a limit of one named supertype.  But this could be extended:
>> 
>>   Predicate<String> p = new Predicate<String>() implements Serializable { ... }
>> 
>> In this case, there is no single-method restriction; you could implement Iterator and Runnable if you wanted:
>> 
>>   new Iterator<T>() implements Runnable { ... }
>> 
>> Note that none of this is serialization-specific; it is simply a way of being explicit about multiple supertypes in contexts there this was not previously allowed.
>> 
>> 
> 



More information about the lambda-spec-observers mailing list