<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<font size="4" face="monospace">Interfaces are allowed to have
(public) fields today, but they are always static. So we're just
talking about access control.<br>
<br>
My point is that I think the anomaly you are really raising is
that access control for interface members is not uniform, but
without a clear justification other than history. Private
_methods_ were introduced into interfaces in Java 8 (to go with
default methods), but there's no good reason why private fields
(interfaces already have fields, they are static) or private
nested classes did not get the same treatment. This is a topic
for potential cleanup at some point.<br>
<br>
But, if I understand your clarification, you are saying: "sealed
classes let me treat all the implementations of a type as being a
single big implementation, and sometimes these might want to share
state, and the sealed class is a sensible place to put state
shared across all implementations"? (And then taking advantage of
the nestmate status of co-declared classes, so that "private"
isn't really private to the interface, but private to the source
file.)<br>
</font><br>
<div class="moz-cite-prefix">On 6/23/2025 8:04 AM, Swaranga Sarma
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAGZD2TCU16cnWGhuNcyTSXKYv+f35+4gSP6Mf5xwiJUZdZdsEg@mail.gmail.com">
<div dir="auto">Hi Brian, I am afraid I am not seeing how I am
making a case for private members in interfaces. That would be
introducing state into an interface and seems pretty large
change to the language spec. </div>
<div dir="auto"><br>
</div>
<div dir="auto">As for the suggestion, yes, the post does make it
seem like it is specific to sealed interfaces but wasn’t
intended as such. I was using it as a real example from my work
which uses a sealed hierarchy. Although now that I think about
it, for regular interfaces I don’t see how it would be helpful
if these fields are private to the interface. </div>
<div dir="auto"><br>
</div>
<div dir="auto">I have felt its need more in sealed interfaces
where I want to share common static fields and methods across
the sub interfaces/records. <br clear="all">
<br clear="all">
<div dir="auto">
<div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">
<div dir="ltr">
<div>Regards<br>
</div>
<div>Swaranga</div>
</div>
</div>
</div>
</div>
<div><br>
</div>
<div><br>
<div class="gmail_quote gmail_quote_container">
<div dir="ltr" class="gmail_attr">On Mon, Jun 23, 2025 at
4:50 AM Brian Goetz <<a href="mailto:brian.goetz@oracle.com" moz-do-not-send="true" class="moz-txt-link-freetext">brian.goetz@oracle.com</a>>
wrote:<br>
</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">
<div> <font size="4" face="monospace" style="font-family:monospace;color:rgb(0,0,0)">What I
see here is an argument for private members in
interfaces, but this has nothing to do with sealed
interfaces. Why is sealing relevant to this suggestion?</font></div>
<div><br>
<br>
<div>On 6/22/2025 11:18 PM, Swaranga Sarma wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>Traditionally Java has not allowed private static
members inside of an interface but now with sealed
interfaces, I am wondering if there is a case to be
made. Here is a real-world use-case where I felt
this was needed recently.</div>
<div><br>
</div>
<div>I have a sealed interface hierarchy for a simple
state machine transition result like below:<br>
<br>
```</div>
<div>sealed interface TransitionCheckResult {</div>
<div> sealed interface BootstrapTransitionCheckResult
extends TransitionCheckResult {</div>
<div> record AllowedTransition(String
destinationStateId, Map<String, String>
metadata) {}</div>
<div> record DisallowedTransition(Map<String,
String> metadata) {}</div>
<div> }</div>
<div><br>
</div>
<div>
<div> sealed interface
IntermediateTransitionCheckResult
extends TransitionCheckResult {</div>
<div> record AllowedTransition(String
destinationStateId, </div>
<div>
Map<String, String> metadata, </div>
<div>
List<Actions> cleanupActions) {}</div>
<div> record DisallowedTransition(Map<String,
String> metadata) {}</div>
<div> }</div>
</div>
<div>}</div>
<div>```</div>
<div><br>
</div>
<div>Basically the "transition check result" is broken
up into a bootstrap transition check result for the
initial state transition check and an "intermediary
transition check result" for an intermediate node in
the state machine each of which have their allowed
and disallowed transitions with slightly varying
attributes. So a sealed interface with records
seemed to fit the bill here.</div>
<div><br>
</div>
<div>Now for the destinationStateId, there are some
constraints like length and Pattern (among others).
I wanted to add a private static final Pattern
variable in the TransitionCheckResult interface
which I then use to validate the passed in
destinationStateId. But unfortunately, this is not
allowed. I think I have the following options none
of which seem great:<br>
</div>
<div>1. Make the Pattern public; no-body else needs
access to the Pattern field so this
feels unnecessary.</div>
<div>2. Move the pattern field to inside the record
class - this would work but I have two records that
require the same validation and either I have to
repeat myself or add the pattern to one of them and
reference it in the other. Again, feels like I
shouldn't have to introduce this otherwise
unnecessary dependency.</div>
<div>3. Create a DestinationStateId record where I can
fully encapsulate the validation in one place and
change the AllowedTransition record declarations to
use this record. This feels like the best approach
but then in another part of the app, I lose the
ability to do switch on the destinationStateId like
this:<br>
<br>
```</div>
<div>static final RESOLVED_STATE_ID = new
PolicyStateId("resolved);</div>
<div>PolicyStateId stateId = ...;</div>
<div>switch(stateId.name()) {</div>
<div> case RESOLVED_STATE_ID.name() -> ... // not
allowed</div>
<div> ...</div>
<div>}</div>
<div>```</div>
<div>There are slight variations of these approaches
(like using a when clause to address the switch
problem or using a static inner Validator class
inside the top-level sealed interface) but it feels
verbose.</div>
<div><br>
</div>
<div>Thoughts? Especially now with sealed interfaces
and records, there could be more cases where this
could be useful.</div>
<div><br>
</div>
<div>
<div dir="ltr" class="gmail_signature" data-smartmail="gmail_signature">
<div dir="ltr">
<div>Regards<br>
</div>
<div>Swaranga</div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
</div>
</blockquote>
</div>
</div>
</blockquote>
<br>
</body>
</html>