Default interface methods aren't considered abstract method implementations

Attila Szegedi szegedia at gmail.com
Mon Feb 10 09:44:47 UTC 2025


 Hi both Chen and Pavel,

Thank you both for answering! I was not specifically asking Brian, of
course, that’s why there’s a wink next to it :-)
I now scoured JLS 23, specifically:

----
8.1.1.1. abstract Classes

A class C has abstract methods if either of the following is true:

Any of the member methods (§8.2) of C - either declared or inherited - is
abstract.

Any of C's superclasses has an abstract method declared with package
access, and there exists no method that overrides the abstract method from
C or from a superclass of C.

8.2. Class Members

The members of a class are all of the following:

Members inherited from its direct superclass type (§8.1.4), except in the
class Object, which has no direct superclass type

Members inherited from any direct superinterface types (§8.1.5)

Members declared in the body of the class (§8.1.7)

8.1.5. Superinterfaces:

Each default method (§9.4.3) of a superinterface of the class may
optionally be overridden by a method in the class; if not, the default
method is typically inherited and its behavior is as specified by its
default body.
-----

And nothing in there tells me unambiguously that my example should’t work
(the last quoted sentence from 8.1.1.1 is weird, but adding “public” to
declaration of “m” circumvents it and it still doesn’t compile.) There are
few phrases that seem open to interpretation though: "default method is
_typically_ inherited” (typically is doing heavy lifting here: sometimes it
isn’t?) and “_any of the member methods_ (§8.2) of C - either declared or
inherited - is abstract" (are A.m() and F.m() treated as separate member
methods at this stage despite identical signatures?)

Again, I’m not arguing current javac behavior is wrong, just trying to
understand why is it right. I actually hit this in an IRL refactoring – had
several classes that both extended an abstract class (A) and implemented an
interface (F), and all these classes had the same implementation for an
abstract method (m) that was actually semantically related to F and it felt
like a good example of DRY to implement the method only once as a default
in F. (Yes, I could create an interim class AF and move the implementation
there, but this felt like it would’ve been a good use of an interface as a
mixin.)

I wonder if I recreated the example in bytecode directly whether the JVM
would load the class successfully (I might need to attempt to also call the
method) or would I get some kind of IncompatibleClassChangeError.

Attila.

On 2025. Feb 10. at 1:58:32, Chen Liang <liangchenblue at gmail.com> wrote:

> Hello guys, amber is for new language features. Questions with java
> compilation or JLS/JVMS belong to the compiler group.
>
> That said, I believe this behavior is most likely a preservation of method
> resolution, that for instance methods, methods from superclass have higher
> priority than methods from interfaces. For example, before Java 8, static
> methods could not be defined in interfaces; and when they were added in 8,
> resolution rule states that they aren't shadowed to child types, so classes
> cannot "inherit" interface static methods, unlike interface static fields.
>
> Another fun fact is that superinterface fields take precedence in
> resolution over superclass fields. Also a legacy from old Java, but I don't
> think that is going to be changed to make things "consistent".
>
> Regards,
> Chen Liang
>
> On Sun, Feb 9, 2025 at 4:26 PM Pavel Rappo <pavel.rappo at gmail.com> wrote:
>
>> Attila,
>>
>> Come to think of it, we should use some other, more narrowly focused,
>> mailing list. Apologies to subscribers of this list. Since lambda-dev
>> is defunct now, perhaps we could use compiler-dev, amber-dev, or
>> core-libs-dev instead. I'm voting for amber-dev, where Brian mostly
>> resides these days.
>>
>> -Pavel
>>
>> On Sun, Feb 9, 2025 at 10:12 PM Pavel Rappo <pavel.rappo at gmail.com>
>> wrote:
>> >
>> > You are not specifically asking Brian, are you? If so, sorry for
>> replying.
>> >
>> > My humble take is that the default method is something to use when
>> > there's nothing else there. When there's something, even if it's
>> > abstract, we use that. So, a default method is a minimally interfering
>> > fallback/extension scenario, if you will.
>> >
>> > That abstract A.m() effectively replaces default F.m() in C as if
>> > F.m() were never there. If F.m() were allowed to provide
>> > implementation for A.m() in C, then some uncompliable code could
>> > suddenly become compilable and operational at runtime.
>> >
>> > -Pavel.
>> >
>> > On Sun, Feb 9, 2025 at 9:04 PM Attila Szegedi <szegedia at gmail.com>
>> wrote:
>> > >
>> > > Hey folks,
>> > >
>> > > I found a somewhat puzzling behavior: default interface methods
>> aren't considered abstract method implementations. Trying to compile this
>> minimal reproducer:
>> > >
>> > > ------ C.java ------
>> > > abstract class A {
>> > >   abstract void m();
>> > > }
>> > >
>> > > interface F {
>> > >   default void m() {}
>> > > }
>> > >
>> > > class C extends A implements F {}
>> > > ------ C.java ------
>> > >
>> > > $ javac C.java
>> > > C.java:9: error: C is not abstract and does not override abstract
>> method m() in A
>> > > class C extends A implements F {
>> > > ^
>> > > 1 error
>> > >
>> > > I can accept this being valid according to JLS today (I tried with
>> 11, 21, and 23.) I admit this is one of rare occasions when I didn't go
>> scouring the JLS to figure out what exactly prevents the compiler from
>> accepting F.m() as implementation of A.m() in C. I'm wondering though if
>> this isn't something that could be improved upon in the future. (I'm sure
>> there's a gotcha somewhere. Right, Brian? ;-) )
>> > >
>> > > Have a great day,
>> > >   Attila.
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20250210/fbea32d0/attachment-0001.htm>


More information about the compiler-dev mailing list