Static method access dilemma and proposal: @NotInherited

Stephen Colebourne scolebourne at
Thu Jun 27 10:20:02 PDT 2013

The addition of static methods on interfaces has given developers a
new very useful tool. However, it has also produced a dliemma.

A static method on a class is accessible/"inherited" by subclasses.
Thus is just as good as for accessing
the static method defined on SuperClass. By contrast, with static
methods on interfaces, this is not possible - a static method on an
interface is not "inherited" (a Good Thing).

The dliemma, from JSR-310
(, is that I _really_
want to avoid the inheritance of static methods from one abstract
class (Chronology), as the methods make no sense at all to be called
on the subclasses, and in fact they may cause bugs. Thus, the new
language feature pushes me to change the abstract class to be an
interface *just to get the new static method behaviour*. In essence I
have to make a new trade off between the right tool for the job
(abstract class) and the right tool to avoid static method bugs

It occured to me that as this was a new dliemma, I should report it
here on lambda-dev. And propose a possible solution.

Consider a new annotation @NotInherited that is only applicable to
static methods. If a developer places it on a static method, then the
method cannot be invoked by subclasses:

public class A {
  public static void foo() {..}
public class B extends A {
{  // other code;  // compiles;  // would not compile with this proposal

- Many IDEs support something similar today, but this would be
enforced at the compiler level.
- It is similar to @Override in conceptual scope, and is therefore
suitable for an annotation.
- It would not change the compiled bytecode at all, other than the
standard storage for the additional annotation.
- There are no reflection, security or backwards compatibility issues
that I can see.
- Adding the annotation to a previously published API would be
backwards incompatible at the source level, but not the binary level
- When compiling B against a previously compiled A, the annotation
would be read from A's bytecode.
- The annotation would not be processed by the JVM or verifier, thus would be valid if it could be compiled (such as in a separate
compilation scenario).
- The change appears to be small, and thus not require a large effort
to implement

The annotation could be added to the JDK without enforcing it in
javac, but that would seem to be a change not worth doing as it would
rely on IDEs.

Its easy to say that this is an old problem and so nothing needs to be
done. But I hope I've tried to indicate that I think lambda's static
methods on interfaces has changed the nature of the old problem and
made it potentially more problematic in code design terms.


More information about the lambda-dev mailing list