<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>