<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">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)"><u></u>
<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>