<p>I saw this in <a href="https://stackoverflow.com/a/4384/697449">an answer to another question</a>, in reference to shortcomings of the Java spec:</p>
<blockquote>
<p>There are more shortcomings and this is a subtle topic. Check <a href="http://kiranthakkar.blogspot.com/2007/05/method-overloading-with-new-features-of.html" rel="noreferrer">this</a> out:</p>
<pre><code>public class methodOverloading{
     public static void hello(Integer x){
          System.out.println(&quot;Integer&quot;);
     }

     public static void hello(long x){
          System.out.println(&quot;long&quot;);
     }

     public static void main(String[] args){
         int i = 5;
         hello(i);
     }
}
</code></pre>
<p>Here &quot;long&quot; would be printed (haven't checked it myself), because the compiler chooses widening over auto-boxing. Be careful when using auto-boxing or don't use it at all!</p>
</blockquote>
<p><em>Are we sure that this is actually an example of widening instead of autoboxing, or is it something else entirely?</em></p>
<p>On my initial scanning, I would agree with the statement that the output would be &quot;long&quot; on the basis of <code>i</code> being declared as a primitive and not an object.  However, if you changed</p>
<pre><code>hello(long x)
</code></pre>
<p>to</p>
<pre><code>hello(Long x)
</code></pre>
<p>the output would print &quot;Integer&quot;</p>
<p>What's really going on here?  I know nothing about the compilers/bytecode interpreters for java...</p>

[{'answer_id': 4932, 'author': 'Mike Stone', 'author_id': 122, 'author_profile': 'https://Stackoverflow.com/users/122', 'pm_score': 3, 'selected': False, 'text': '<p>Yes it is, try it out in a test.  You will see "long" printed.  It is widening because Java will choose to widen the int into a long before it chooses to autobox it to an Integer, so the hello(long) method is chosen to be called.</p>\n\n<p>Edit: <a href="https://stackoverflow.com/questions/4242/why-cant-i-call-tostring-on-a-java-primitive#4384">the original post being referenced</a>.</p>\n\n<p>Further Edit: The reason the second option would print Integer is because there is no "widening" into a larger primitive as an option, so it MUST box it up, thus Integer is the only option.  Furthermore, java will only autobox to the original type, so it would give a compiler error if you leave the hello(Long) and removed hello(Integer).</p>\n'}, {'answer_id': 5091, 'author': 'Camilo Díaz Repka', 'author_id': 861, 'author_profile': 'https://Stackoverflow.com/users/861', 'pm_score': 5, 'selected': True, 'text': '<p>In the first case, you have a widening conversion happening. This can be see when runinng the "javap" utility program (included w/ the JDK), on the compiled class:</p>\n\n<pre><code>public static void main(java.lang.String[]);\n  Code:\n   0:   iconst_ 5\n   1:   istore_ 1\n   2:   iload_ 1\n   3:   i2l\n   4:   invokestatic    #6; //Method hello:(J)V\n   7:   return\n\n}\n</code></pre>\n\n<p>Clearly, you see the I2L, which is the mnemonic for the widening Integer-To-Long bytecode instruction. See reference <a href="http://java.sun.com/docs/books/jvms/second_edition/html/Instructions2.doc6.html" rel="noreferrer">here</a>.</p>\n\n<p>And in the other case, replacing the "long x" with the object "Long x" signature, you\'ll have this code in the main method:</p>\n\n<pre><code>public static void main(java.lang.String[]);\n  Code:\n   0:   iconst_ 5\n   1:   istore_ 1\n   2:   iload_ 1\n   3:   invokestatic    #6; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;\n   6:   invokestatic    #7; //Method hello:(Ljava/lang/Integer;)V\n   9:   return\n\n}\n</code></pre>\n\n<p>So you see the compiler has created the instruction Integer.valueOf(int), to box the primitive inside the wrapper.</p>\n'}, {'answer_id': 5164, 'author': 'dlinsin', 'author_id': 198, 'author_profile': 'https://Stackoverflow.com/users/198', 'pm_score': 2, 'selected': False, 'text': '<p>Another interesting thing with this example is the method overloading. The combination of type widening and method overloading only working because the compiler has to make a decision of which method to choose. Consider the following example:</p>\n\n<pre><code>public static void hello(Collection x){\n   System.out.println("Collection");\n}\n\npublic static void hello(List x){\n   System.out.println("List");\n}\n\npublic static void main(String[] args){\n   Collection col = new ArrayList();\n   hello(col);\n}\n</code></pre>\n\n<p>It doesn\'t use the run-time type which is List, it uses the compile-time type which is Collection and thus prints "Collection". </p>\n\n<p>I encourage your to read <a href="http://books.google.com/books?id=ZZOiqZQIbRMC" rel="nofollow noreferrer">Effective Java</a>, which opened my eyes to some corner cases of the JLS.</p>\n'}]
['https://Stackoverflow.com/questions/4922', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/670/']