title: Java: compile-time resolution and "most specific method"
body: <p>The overloaded functions <code>compute1()</code>, <code>compute2()</code>, and <code>compute5()</code> cause compilation errors if you try to use them below:</p>
  
  <pre><code>package com.example.test.reflect;
  
  class JLS15Test2
  {
      int compute1(Object o1, Integer i, Integer j)         { return 1; }
      int compute1(String s1, Integer i, int j)             { return 2; }
  
      int compute2(Object o1, Integer i, int j)             { return 3; }
      int compute2(String s1, Integer i, Integer j)         { return 4; }
  
      int compute3(Object o1, Integer i, int j)             { return 5; }
      int compute3(String s1, Integer i, int j)             { return 6; }
  
      int compute4(Object o1, Integer i, Integer j)         { return 7; }
      int compute4(String s1, Integer i, Integer j)         { return 8; }
  
      int compute5(Object o1, Integer i, Object j)          { return 9; }
      int compute5(String s1, Integer i, int j)             { return 10; }
  
  
      public static void main(String[] args) 
      {
          JLS15Test2 y = new JLS15Test2();
  
          // won't compile:
          // The method compute1(Object, Integer, Integer) is ambiguous 
          // for the type JLS15Test2
          // System.out.println(y.compute1("hi", 1, 1));
  
          // Neither will this (same reason)
          // System.out.println(y.compute2("hi", 1, 1));
          System.out.println(y.compute3("hi", 1, 1));
          System.out.println(y.compute4("hi", 1, 1));
  
          // neither will this (same reason)
          // System.out.println(y.compute5("hi", 1, 1));
      }
  }
  </code></pre>
  
  <p>After reading the JLS section 15.12, I think I understand... in phase 2 (boxing/unboxing allowed, no varargs) of matching overloaded methods, when determining the "most specific method", the JLS says (in effect) that the most specific method is the one whose formal parameters are subtypes of other applicable methods, and primitives and Objects (e.g. <code>int</code> and <code>Integer</code>) are never subtypes of each other. So <code>Integer</code> is a subtype of <code>Integer</code>, and <code>int</code> is a subtype of <code>int</code>, but <code>Integer</code> and <code>int</code> are incompatible w/r/t subtype comparisons, so neither of the <code>compute1()</code>/<code>compute2()</code> pairs have a most specific method.</p>
  
  <p>(Whereas in <code>compute3()</code> and <code>compute4()</code> the method with the <code>String</code> argument is more specific than the method with the <code>Object</code> argument, so the program prints 6 and 8.)</p>
  
  <p>Is my reasoning correct?</p>