Static method access dilemma and proposal: @NotInherited

Brian Goetz brian.goetz at
Thu Jun 27 11:14:34 PDT 2013

Total agreement that it was a mistake to have them be inheritable. 
Static methods in interfaces don't have this defect.  (And we took a hit 
for that inconsistency.)  Unfortunately what you suggest for 9 is 
impractical for compatibility reasons.

Overall I like Stephen's proposal here (except I am not convinced that 
it is suitable for an annotation, but that's a pretty superficial aspect 
of it.)  Anything that moves us towards being able to fix this problem 
over time is good.

On 6/27/2013 1:50 PM, Paul Benedict wrote:
> Stephen, it's an interesting idea. Bikeshed moment.... At the cost of
> having to recompile future code, I'd rather wish to have static methods on
> classes not be inheritable in JDK 9 and onward. Then the same behavior can
> be predictable across classes or interfaces. Fixing a bad language design
> is probably better than patching things up with @NotInherited.
> On Thu, Jun 27, 2013 at 12:20 PM, Stephen Colebourne
> <scolebourne at>wrote:
>> 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
>> (interface).
>> 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 {
>>    @NotInherited
>>    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.
>> Thoughts?
>> Stephen

More information about the lambda-dev mailing list