Note that there are some explanatory texts on larger screens.

plurals
  1. PODiffering behaviour between Java 5 & 6 when overloading generic methods
    text
    copied!<p>I've run into an issue in Java's Generics in which the same code will compile and work fine in Java 6, but will fail to compile because of the same erasure in Java 5. I have a file TestErasure.java that has an overloaded method, called "method":</p> <pre><code>import java.util.ArrayList; import java.util.List; public class TestErasure { public static Object method(List&lt;Object&gt; list) { System.out.println("method(List&lt;Object&gt; list)"); return null; } public static String method(List&lt;String&gt; list) { System.out.println("method(List&lt;String&gt; list)"); return null; } public static void main(String[] args) { method(new ArrayList&lt;Object&gt;()); method(new ArrayList&lt;String&gt;()); } } </code></pre> <p>In Java 5, I get the expected compilation error, stating that the erasure of "method" is the same:</p> <pre><code>$ javac -version javac 1.5.0_19 $ javac TestErasure.java TestErasure.java:10: name clash: method(java.util.List&lt;java.lang.String&gt;) and method(java.util.List&lt;java.lang.Object&gt;) have the same erasure public static String method(List&lt;String&gt; list) { ^ TestErasure.java:17: method(java.util.List&lt;java.lang.Object&gt;) in TestErasure cannot be applied to (java.util.ArrayList&lt;java.lang.String&gt;) method(new ArrayList&lt;String&gt;()); ^ 2 errors </code></pre> <p>However, Java 6 is able to compile and run this same code.</p> <pre><code>$ javac -version javac 1.6.0_16 $ javac TestErasure.java $ java TestErasure method(List&lt;Object&gt; list) method(List&lt;String&gt; list) </code></pre> <p>Based upon my current understanding of erasures (thanks to <a href="https://stackoverflow.com/questions/313584/what-is-the-concept-of-erasure-in-generics-in-java">Jon Skeet</a> and <a href="http://www.angelikalanger.com/GenericsFAQ/FAQSections/TechnicalDetails.html#FAQ802" rel="nofollow noreferrer">Angelika Langer</a>), I actually expected the compilation error as thrown by Java 5 (unless something changed in how Java handled Generics--which I can not find on the Java 6 release notes). In fact, if I modify the return type of one of the overloaded methods:</p> <pre><code>public static Object method(List&lt;Object&gt; list) ... public static Object method(List&lt;String&gt; list) ... </code></pre> <p>Java 6 also fails to compile because of the same erasures:</p> <pre><code>$ javac TestErasure.java TestErasure.java:5: name clash: method(java.util.List&lt;java.lang.Object&gt;) and method(java.util.List&lt;java.lang.String&gt;) have the same erasure public static Object method(List&lt;Object&gt; list) { ^ TestErasure.java:10: name clash: method(java.util.List&lt;java.lang.String&gt;) and method(java.util.List&lt;java.lang.Object&gt;) have the same erasure public static Object method(List&lt;String&gt; list) { ^ 2 errors </code></pre> <p>It appears as if the return type in Java 6 somehow influences the selection of which overloaded method to use?</p> <p>Can someone shed light on why the first example works in Java 6--it seems to go against the stated handling of overloaded generic methods?</p> <p>More info:</p> <p>Per David's suggestion, the original example, complied by javac 1.6, will run under the java 1.5:</p> <pre><code>$ javac -target 1.5 TestErasure.java $ java -version java version "1.5.0_19" $ java TestErasure method(List&lt;Object&gt; list) method(List&lt;String&gt; list) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload