<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    <font size="4"><font face="monospace">In a previous life, I was
        involved in several static analysis efforts.  One of the common
        factors there is that annotations like
        @ShouldntIgnoreReturnValue or @ShouldWashYourHands is that these
        are always approximations, guidelines aimed at identifying
        _likely bugs_ rather than _invalid programs_.  Usually such
        annotations beget requests for more annotations to refine the
        behavior in increasingly rarefied corners. 
        @OverrideShouldInvoke seems like it would be equally subject to
        this; it's a good starting point for "this is what the
        superclass intends", but is unlikely to be precise enough to not
        create new problems.  <br>
        <br>
        The language, on the other hand, should mostly be in the
        business of identifying _invalid programs_.  If something is
        important enough that the language should reject a program over
        it, it should probably be part of the language, not an
        annotation.  (An obvious exception is @Override; in hindsight,
        it was probably excessive exuberance to use the new shiny
        annotation tool for this, rather than introducing a conditional
        `override` keyword at the time (Java 5).) <br>
        <br>
        So my gut sense is that this belongs in an effort like Checkers
        rather than in the language itself.  <br>
      </font></font><br>
    <div class="moz-cite-prefix">On 2/9/2023 11:07 AM, Archie Cobbs
      wrote:<br>
    </div>
    <blockquote type="cite" cite="mid:CANSoFxuRnN97Q83Z1kV3oCDi81V0eHUxfMTbqtUwh9ugzRbwew@mail.gmail.com">
      
      <div dir="ltr">
        <div>Just throwing this out there - I'm curious whether this
          idea resonates with anyone else... or alternately offends...</div>
        <div><br>
        </div>
        <div>First, a big picture observation:</div>
        <div><br>
        </div>
        <div>There is a lot of "activity" in Java centered around the
          superclass-subclass relationship. For example, we have the <span style="font-family:monospace">protected</span> keyword. We
          have the <span style="font-family:monospace">final</span>
          keyword. We have a bunch of rules around how constructors are
          allowed (or not allowed) to invoke <span style="font-family:monospace">super()</span>. We have <span style="font-family:monospace">@Overrides</span>. We have <span style="font-family:monospace">abstract</span> methods that
          force behavior on subclasses.<br>
        </div>
        <div><br>
        </div>
        <div>Basically, all of this stuff amounts to a somewhat ad hoc
          "API" that a superclass defines and a subclass uses (and in
          some cases, vice-versa).<br>
        </div>
        <div><br>
        </div>
        <div>But this "API" is not always clearly or fully defined. For
          example, bugs caused by 'this' escapes result from what can be
          described as an ambiguity in the "API" between superclass and
          subclass.<br>
        </div>
        <div><br>
        </div>
        <div>I guess I'm just saying that this "API" and how we define
          it (or fail to define it) is an area of interest to me.<br>
        </div>
        <div><br>
        </div>
        <div>OK, back to earth...</div>
        <div><br>
        </div>
        <div>Here's a proposal that addresses one more little bit of
          this "API". I'm on the fence as to whether this would be
          worthwhile and am curious what others think.<br>
        </div>
        <div><br>
        </div>
        <div>The problem is this: often a superclass method <span style="font-family:monospace">foo()</span> implements some
          important superclass functionality, but it is not final so
          that it can be overridden. In these cases, the superclass
          often wants to be able to specify "If you override this
          method, then you should also invoke <span style="font-family:monospace">super.foo()</span> at some
          point unless you really know what you're doing". An example of
          such a method is <span style="font-family:monospace">Object.finalize()</span>.</div>
        <div><br>
        </div>
        <div>There are arguments that such methods are bad style -
          instead, there should be a separate empty method provided for
          subclasses to override. So this idea would have to be weighed
          against that. But regardless, today there are lots of examples
          of such methods out there already.<br>
        </div>
        <div><br>
        </div>
        <div>The rough proposal is:</div>
        <div>
          <ul>
            <li>Add a new annotation <span style="font-family:monospace">@OverrideShouldInvoke</span>.
              If a method <span style="font-family:monospace">Sub.foo()</span>
              overrides a superclass method <span style="font-family:monospace">Sup.foo()</span> that has
              an <span style="font-family:monospace">@OverrideShouldInvoke</span>
              annotation, and nowhere in <span style="font-family:monospace">Sub.foo()</span> does it
              invoke <span style="font-family:monospace">Sup.foo()</span>
              (via a <span style="font-family:monospace">super.foo()</span>
              expression), then an error occurs.<br>
            </li>
            <li>Add a new property <span style="font-family:monospace">boolean
                withoutInvokingSuper default false</span> to the <span style="font-family:monospace">@Overrides</span>
              annotation that allows <span style="font-family:monospace">Sub.foo()</span> to
              suppress this error if it "really knows what it's doing".<br>
            </li>
          </ul>
        </div>
        <div>For simplicity, we'd only count invocations of the
          overridden method exactly, not some overloaded variant. So for
          example if an override of <span style="font-family:monospace">ArrayList.add(E)</span>
          invoked <span style="font-family:monospace">super.add(int, E)</span>,
          that wouldn't count. Or, if you wanted to get fancy, you could
          make this optional via something like <span style="font-family:monospace"><a class="gmail_plusreply" id="plusReplyChip-4" moz-do-not-send="true">@Override</a>ShouldInvoke(allowOverloads
            = true)</span>.<br>
        </div>
        <div><br>
        </div>
        <div>Here's are some examples of where you might want to use
          this:</div>
        <div><br>
        </div>
        <div style="margin-left:40px"><span style="font-family:monospace">public class Object {</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace"><br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    <a class="gmail_plusreply" id="plusReplyChip-3" moz-do-not-send="true">@OverrideShouldInvoke</a></span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    protected native Object
            clone() throws CloneNotSupportedException;</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace"><br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    @OverrideShouldInvoke<br>
                protected void finalize() throws Throwable {<br>
                    ...<br>
                }</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">}</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace"><br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">public class FileOutputStream
            extends OutputStream {</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace"><br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    <span style="font-family:monospace"><span style="font-family:monospace"><a class="gmail_plusreply" id="gmail-plusReplyChip-3" moz-do-not-send="true">@OverrideShouldInvoke</a></span></span></span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    public void close() throws
            IOException {</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">        ...</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    }<br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">}</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace"><br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">public abstract class
            AbstractExecutorService implements ExecutorService {</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace"><br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    <span style="font-family:monospace"><a class="gmail_plusreply" id="gmail-plusReplyChip-3" moz-do-not-send="true">@OverrideShouldInvoke</a></span></span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    public Future<?>
            submit(Runnable task) {</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">        ...</span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">    }<br>
          </span></div>
        <div style="margin-left:40px"><span style="font-family:monospace">}<br>
          </span></div>
        <div><br>
        </div>
        <div>Thoughts?<br>
        </div>
        <div><br>
        </div>
        <div>-Archie</div>
        <div><br>
        </div>
        <div>--<br>
        </div>
        <div>
          <div dir="ltr" data-smartmail="gmail_signature">Archie L.
            Cobbs<br>
          </div>
        </div>
      </div>
    </blockquote>
    <br>
  </body>
</html>