Why are certain Object methods not callable from default methods?
Asked Answered
B

1

7

When creating a default method in Java 8, certain Object methods are not callable from within the default method. For example:

interface I {
    default void m() {
        this.toString(); // works.
        this.clone(); // compile-time error, "The method clone() is undefined for the type I"
        this.finalize(); // same error as above.
    }
}

It seems that clone() and finalize() are the only methods from Object that are not allowed. Coincidently, these are the only methods of Object that are protected, but this question is in particular regard to default methods, as they will be inherited by classes that do extend java.lang.Object. What is the reason for this?

Bosh answered 27/4, 2016 at 15:38 Comment(2)
Possible duplicate of Why is the clone() method protected in java.lang.Object?Corcoran
@SPrashad I disagree. That question has nothing to do with why it's not callable in an interface's default method.Judaist
J
8

It's not a coincidence that the protected methods from Object are not available in a default method in an interface.

Section 9.2 of the JLS states:

If an interface has no direct superinterfaces, then the interface implicitly declares a public abstract member method m with signature s, return type r, and throws clause t corresponding to each public instance method m with signature s, return type r, and throws clause t declared in Object, unless an abstract method with the same signature, same return type, and a compatible throws clause is explicitly declared by the interface.

An interface will not inherit anything from Object, but it will implicitly declare all public Object methods. This does not include any protected methods. This explains why clone and finalize can't be called; they are not declared in an interface.

Judaist answered 27/4, 2016 at 15:45 Comment(4)
Interesting. I wasn't aware that interfaces do not inherit from Object when they declare default method. However, you cannot call a default method directly; it must be called on an object whose class directly or indirectly implements the interface. That class will no doubt inherit from Object. Thus, it should be safe to allow for this. Interesting design decision.Bosh
@RaffiKhatchadourian Just to clarify, interfaces never inherit from Object, regardless of whether there is a default method or not. They simply don't. The problem with inheriting from Object is that for example the toString() method could be overridden by any class implementing I, so which implementation should be chosen then? The one inherited by the interface or the one in the class that implements the interface?Yarborough
@Yarborough If it's the case that interfaces never inherit from Object, then why is Object o = i; where i has a compile-time type of an interface legal? Actually, this seems related to #6056624.Bosh
It is legal due to this specific clause: The type Object, if C is an interface type with no direct superinterfaces (§9.1.3).. But this has no relevance as to inheritance, that is controlled by superclass/superinterface relationships. Interface types still don't inherit methods from Object. It only implicitly declares the same methods. The difference is rather subtle and seems unnecessary, but it exists.Yarborough

© 2022 - 2024 — McMap. All rights reserved.