Would using covariant return type in clone really break compatibility?
<p>I've recently encountered <a href="http://stackoverflow.com/questions/3751160/why-doesnt-java-5-api-take-advantage-of-covariant-return-types">Why doesn&#39;t Java 5+ API take advantage of covariant return types?</a>. </p>

<p>I agree with the Question, in Java 5 JDK developers could have used covariant return type for clone and changed existing classes so we could write</p>

<pre><code>ArrayList&lt;String&gt; list = new ArrayList&lt;String&gt;();
ArrayList&lt;String&gt; clone = list.clone();
</code></pre>

<p>instead of</p>

<pre><code>ArrayList&lt;String&gt; clone = (ArrayList&lt;String&gt;)list.clone();
</code></pre>

<p>but by some reasons the did not do that.</p>

<p>I've done some experiments changing my <code>test.ArrayList.clone</code> return type from Object to  ArrayList to see if "Previously compiled classes cannot find the method with the new return type" but could not reproduce the problem. In the bytecode, a call to old <code>test.ArrayList.clone</code> looks like</p>

<pre><code> INVOKEVIRTUAL test.ArrayList.clone()Ljava/lang/Object;
</code></pre>

<p>that is, the method signature contains return type, so after my change its signature changes to <code>test.ArrayList.clone()Ltest.ArrayList</code>. So it seems that old class will break, but in fact it doesn't because there are 2 clone methods in test.ArrayList.class</p>

<pre><code>  public clone()Ltest.ArrayList;
  public bridge clone()Ljava/lang/Object; 
</code></pre>

<p>the second one is a bridge, all it does is calling the covariant version</p>

<pre><code> ...
 INVOKEVIRTUAL ArrayList.clone()Ltest.ArrayList;
 ...
</code></pre>

<p>so old classes continue working with no problem. </p>

<p>Can anyone explain how changing clone's return type can break the bytecode?</p>
