title: How type inference work for method calls?
body: <p>Consider the following example:</p>
  
  <pre><code>public class Learn {
      public static &lt;T&gt; T test (T a, T b) {
          System.out.println(a.getClass().getSimpleName());
          System.out.println(b.getClass().getSimpleName());
          b = a;
          return a;
      }
  
      public static void main (String[] args) {
          test("", new ArrayList&lt;Integer&gt;());
      }
  }
  </code></pre>
  
  <p>In the <code>main</code> method, I am calling <code>test</code> with a <code>String</code> and an <code>ArrayList &lt;Integer&gt;</code> object. Both are different things and assigning an <code>ArrayList</code> to <code>String</code> (generally) gives a compile error.</p>
  
  <pre><code>String aString = new ArrayList &lt;Integer&gt; (); // won't compile
  </code></pre>
  
  <p>But I am doing exactly that in the 3rd line of <code>test</code> and the program compiles and runs fine. First I thought that the type parameter <code>T</code> is replaced by a type that's compatible with both <code>String</code> and <code>ArrayList</code> (like <code>Serializable</code>). But the two <code>println</code> statements inside <code>test</code> print "String" and "ArrayList" as types of <code>a</code> and <code>b</code> respectively. My question is, if <code>a</code>is <code>String</code> and <code>b</code> is <code>ArrayList</code> at runtime, how can we assign <code>a</code> to <code>b</code>.</p>