Refinements for sealed types

Alex Buckley alex.buckley at
Wed Aug 21 19:38:58 UTC 2019

// Declarations of RedFruit/BlueFruit corrected below from `extends 
Node` to `extends Fruit`

I don't know what I don't know about "aux classes". I do know that if 
you don't nest the concrete leaves, they can't be public in the same 
compilation unit:
public sealed interface Fruit {  // permits RedFruit, BlueFruit
   /* public */ sealed interface RedFruit extends Fruit {}
                                  // permits *berry
   /* public */ sealed interface BlueFruit extends Fruit {}
                                  // permits Blueberry
   /* public sealed */ class FruitCake implements Fruit {}
                                  // permits nothing; implicitly final
/* package-access */ class Strawberry implements Fruit.RedFruit {}
/* package-access */ class Raspberry  implements Fruit.RedFruit {}
/* package-access */ class Blueberry  implements Fruit.BlueFruit {}

Putting the concrete leaves in another compilation unit so they can be 
public (assume that's the right accessibility) isn't ceremony reduction. 
Am I missing something about how this hierarchy should be declared?


On 8/20/2019 5:05 PM, Brian Goetz wrote:
> I do, because the other way to get a class into the same compilation unit, aux classes, have some limitations.  So we’re encouraging the pattern of nesting.  But … I am not sure we want to push it all the way.  Consider a type like:
>      sealed interface Fruit {
>          interface RedFruit extends Fruit { }
>          interface BlueFruit extends Fruit { }
>          class Strawberry implements RedFruit { }
>          class Raspberry implements RedFruit { }
>          class Blueberry implements BlueFruit { }
>      }
> Do we want to force Blueberry to be Fruit.BlueFruit.Blueberry (or at least, twist the user’s arm into it by offering less ceremony?)  I think that would be lame — and worse than lame if the intermediate interfaces (RedFruit, BlueFruit) were not public.  Then we’d be nesting the public types in the nonpublic ones, and they’d be inaccessible.
>> You often show the concrete classes as members of a sealed interface. Interface members are already implicitly public and static; is this a precedent to build on for a sealed interface? That is, have the nested concrete classes be implicitly final, and have the interface's implicit `permits` list care about only nested concrete classes. Top level concrete classes in the same compilation unit would be handed like concrete classes in other compilation units: nothing different than today.
>> Layering sealing on top of nesting has the attraction that it avoids putting multiple public concrete classes in a single compilation unit. It's right that the concrete leaves are public, but javac dislikes compilation units with multiple public types.
>> Alex

More information about the amber-spec-experts mailing list