Sealed types

Kevin Bourrillion kevinb at
Fri Nov 30 20:49:12 UTC 2018

On Thu, Nov 29, 2018 at 5:42 PM Brian Goetz <brian.goetz at> wrote:

> I suspect we ought to *recommend* use of `permits` as a kindness to users
>> who aren't always looking at javadoc, so they can actually see what to
>> switch over. Maybe requiring `permits` always is too much though (it also
>> precludes anonymous subtypes, but then again those are of limited value
>> anyway, aren't they?).
> I worry that *requiring *this will feel heavyweight,

Yes, I was musing but I also agree not to require it. The style
recommendation should really just be "make sure it's pretty easy for users
to know what all the subtypes are - whether that means listing them with
`permits` or just keeping them all nearby or whatever."

So back to the current state. I'm not 100% following why `permits`
> shouldn't just be additive when present. That avoids the "cliff" and we do
> generally trust source files to not misuse *themselves*.
> In nearly all the use cases I have in mind, either the subtypes are
> declared all together, or they are strewn about the file system.  I have a
> harder time imagining the case where you have 20 that are co-declared, and
> one that is elsewhere; that’s the case in which the additive interpretation
> would pay for itself. Can you think of situations in which this would arise
> regularly?

I could run statistics on how commonly classes get subtyped inside vs.
outside the package. I could review anomalous cases like "13 within but
also 2 outside" to see if it gives us any ideas. (And btw, if not this,
please do rack your brain for what other kinds of stats from Our Weird
Codebase might be informative for this feature, even if they are just to
confirm what we already "know"...)

*Transitivity.* Sealing is transitive; unless otherwise specified, an
>> abstract subtype of a sealed type is implicitly sealed, and a concrete
>> subtype of a sealed type is implicitly final.
> This can be reversed by explicitly modifying the subtype with the
>> non-sealed or non-final modifiers.
> (FWIW, I found the idea of an unsealed subtype of a sealed supertype
> massively confusing for a good while until I finally figured out why
> there's nothing wrong with it.)
> An unsealed subCLASS of a sealed super type can be a very useful move (see
> DynamicConstnatDesc in JEP-334), but an unsealed subINTERFACE is harder to
> grok, because interfaces (absent sealing) lack the ability to constrain
> their subclasses very much (no protected members, no final methods, no
> nonpublic constructors.)

That's interesting; I had just come to the position that it's fine in
either case, because it still means the user knows a total-covering set of
subtypes. It's just that they're not leaf types, but callers usually never
know/care whether they're dealing the real leaf types anyway.

> Do you mean the last statement above as "respectively" (non-sealed can
> counteract implicit sealed of abstract; non-final can counteract implicit
> final of concrete), or does `non-sealed` also work to counteract the
> implicit final of a concrete class? For that matter shouldn't `sealed`
> implicit undo the implicit `final` of a concrete class? I admit to still
> being fairly confused right now.
> Your confusion is a good argument to consider the syntactic choice of
> retconning final, rather than adding sealing :)

Exactly! :-) I hope it pans out.

(Syntax: I assume that the syntax is still malleable and not what needs to
> be debated here and now. Nevertheless, I don't want to miss my chance to
> object to the hyphenation for the record. These won't be seen as two new
> keywords, but as a modifier-modifier, and users will not understand when
> `non-` works and when it doesn't. I think `unsealed` and `nonfinal`
> keywords would be better. `nonfinal` still has its own problems of seeming
> more widely applicable than it is…)
> Not to continue this tangent, but just to backpedal a bit on what I said:
I've now reviewed all the current modifiers and I see that there aren't
really any other very compelling cases where you'd want `non-*` anyway. So,
all right I guess.

Kevin Bourrillion | Java Librarian | Google, Inc. | kevinb at
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <>

More information about the amber-spec-experts mailing list