Refinements for sealed types
Alex Buckley
alex.buckley at oracle.com
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:
--Fruit.java--
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?
Alex
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