<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4" face="monospace">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><br>
    <br>
    <div class="moz-cite-prefix">On 6/22/2025 11:18 PM, Swaranga Sarma
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CAGZD2TCFF_0HEECJ=14bee5A=jH5n-a5d8RSwGgfdC1XfXdr9A@mail.gmail.com">
      
      <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>
  </body>
</html>