Question: Need to understand why in case of Program 1 getting this misleading error, but in Program 2 it gives correct error? Also why unlike toString(),
equals(Object),
and hashCode(),
overriding clone()
and finalize()
inside interface is allowed?
Program 1
For below program getting misleading error:
FOO.java:10: error: finalize() in Object cannot implement finalize() in ClonerFinalizer
public class FOO implements ClonerFinalizer {
^
attempting to assign weaker access privileges; was public
interface ClonerFinalizer {
default Object clone() {
System.out.println("default clone"); return this;
}
default void finalize() {
System.out.println("default finalize");
}
}
public class FOO implements ClonerFinalizer {
// @Override
// public Object clone() {
// return ClonerFinalizer.super.clone();
// }
// @Override
// public void finalize() {
// ClonerFinalizer.super.finalize();
// }
public static void main(String... args) {
new FOO().clone();
new FOO().finalize();
}
}
But if uncommenting above commented code then it gives correct output.
Program 2
Unlike above program in below program clear/correct error
FOO.java:2: error: default method toString in interface ToStringer overrides a member of java.lang.Object
default String toString() {
^
1 error
interface ToStringer {
default String toString() {
System.out.println("default clone"); return "HI";
}
}
public class FOO implements ToStringer {
@Override
public String toString() {
return ToStringer.super.toString();
}
public static void main(String... args) {
new FOO().toString();
}
}
When a class inherits a method from an interface and from its superclass, the superclass method has precedence. This is regardless of whether any of the methods is abstract
.
Therefore, when your FOO
class does not declare the clone()
and finalize()
methods, it will inherit the protected
methods from its superclass. The fact that the interface’s methods are default
does not matter here. But the fact that these interface methods are implicitly public
does matter, as the inherited protected
methods are incompatible with the interface’s public
declarations.
That’s exactly what the error message tells you, the inherited protected “finalize() in Object” cannot implement the public interface method “finalize() in ClonerFinalizer” because that would “assign weaker access privileges”.
The fact that superclass methods have precedence implies that you can never override a class’s method with an interface’s default
method and therefore, it is impossible to provide an implementation for any of the methods of java.lang.Object
without redeclaring the method in the implementation class.
The additional rule that you can’t override methods of Object
with default
methods is not necessary to enforce this. It’s just there to keep you from trying, so you don’t waste your time.
The reason why this doesn’t prevent you from declaring a clone()
or finalize()
method is simple: these declarations do not override a method.
Interfaces can’t have protected
methods, hence, these protected
methods do not exist in the interface in the first place and your declaration is not overriding them. You can check this by adding an @Override
annotation—it will cause a compiler error as the method does not override a method.