The following code compiles w/o errors
No it doesn't.
That error you see is in fact a compile error.
Why you get that error
I'm not sure if you understand that clone()
is, itself, a method that java.lang.Object
already has: javadoc of Object.clone().
A default
implementation in an interface never overrides any implementation found anywhere in a class's actual class hierarchy. Meaning, your clone()
default impl in your IClonable
interface is never used - as all classes have Object
in their hierarchy and its clone()
takes precedence.
However, IClonable
must have a public
clone()
method - but the clone()
you get 'for free' from j.l.Object
is protected
, hence your code does not compile here.
Is it possible to overcome?
Sure. Various options exist.
The best: Don't call it clone()
Given that clone()
is already taken by j.l.Object, find another word. Unless, of course, your intent was to use an interface to force both a default impl and force it public, in which case...
Use abstract classes instead
If ICloneable
was an abstract class, you wouldn't get this error.
... otherwise
No, this cannot be fixed. There is no way to tell javac
to take the default impl of an interface even though an impl exists in the class hierarchy.
NB: Using IClonable
style naming is discouraged. Using the clone()
functionality sort of half baked into java (and Object's own clone()
is part of this functionality) is strongly discouraged. Make immutable types where possible. If not possible, think through what cloning might mean and just make a method for it. The general principle of 'you can clone me' is broken as a concept. For example, cloning an immutable is pointless, yet, having the clone()
method of an immutable type be written as public Object clone() { return this; }
is misleading. As a concept, it's not salvagable. There's a reason e.g. arraylist has new ArrayList<T>(otherArraylist)
as suggested way to clone one, not List<T> clone = otherArrayList.clone();
.