title: code flows to unexpected overloaded method
body: <p>I got an assignment for a course i am taking in CS.</p>
  
  <p>One of the questions has has some classes and a main method and i am asked what will be the output and through which method the code will go.</p>
  
  <p>I worked it out in my head by following the code. After that i ran the code to see what would happen. and what happened really surprised me. It looks like the reference of the object changes the method the JVM selects.</p>
  
  <p>How is it possible that cases 2 and 4 goes to method 1 but case 3 goes to method 3. I would really like to understand what is happening.</p>
  
  <p>class AA:</p>
  
  <pre><code>public class AA
  {
  private int _val=0;
  public AA()
  {
      _val = 5;
  }
  public AA(int val)
  {
      _val = val;
  }
  public int getVal()
  {
      return _val;
  }
  public void setVal(int val)
  {
      _val = val;
  }
  public String toString()
  {
      return "val ="+_val;
  }
  }
  </code></pre>
  
  <p>class BB:</p>
  
  <pre><code>public class BB extends AA
  {
  private String _st;
  
  public BB()
  {
      _st = "bb";
  }
  public BB(String st, int val)
  {
      super(val);
      _st = st;
  }
  public String getSt()
  {
      return _st;
  }
  
  // 1
  public boolean equals(Object ob)
  {
      if ((ob != null) &amp;&amp; (ob instanceof BB))
      {
          if(_st.equals(((BB)ob)._st)&amp;&amp;(getVal() == ((BB)ob).getVal()))
          {
              System.out.println("fun 1: true");
              return true;
          }
  
      }
      System.out.println("fun 1: false");
      return false;
  }
  // 2
  public boolean equals(AA ob)
  {
      if ((ob != null) &amp;&amp; (ob instanceof BB))
      {
          if (_st.equals(((BB) ob)._st)&amp;&amp; (getVal() == ((BB)ob).getVal()))
          {
              System.out.println("fun 2: true");
              return true;
          }
      }
      System.out.println("fun 2: false");
      return false;
  }
  // 3
  
  public boolean equals(BB ob)
  {
      if (ob != null)
      {
          if (_st.equals(((BB) ob)._st)&amp;&amp; (getVal() == ((BB)ob).getVal()))
          {
              System.out.println("fun 3: true");
              return true;
          }
      }
      System.out.println("fun 3: false");
      return false;
  }
  }
  </code></pre>
  
  <p>and this is the main:</p>
  
  <pre><code>public class Driver
  {
  public static void main (String[] args)
  {
      AA a1 = new AA();
      AA a2 = new BB();
      AA a3 = new AA();
      AA a4 = new BB();
      BB b1 = new BB();
      BB b2 = new BB();
  
      //12
      System.out.println("12: a3 equals a1 is " +a3.equals(a1));
      //13
      System.out.println("13: a4 equals a2 is " + a4.equals(a2));
      //14
      System.out.println("14: a1 equals a2 is " +a1.equals(a2));
      //15
      System.out.println("15: a2 equals b1 is " +a2.equals(b1));
      //16
      System.out.println("16: b1 equals a1 is " +b1.equals(a1));
      //17
      System.out.println("17: b2 equals b1 is " +b2.equals(b1));
      //18
      System.out.println("18: b1 equals a4 is " +b1.equals(a4));
  }
  }
  </code></pre>
  
  <p>the output that i am getting is this:</p>
  
  <pre><code>1: a3 equals a1 is false
  fun 1: true
  2: a4 equals a2 is true
  3: a1 equals a2 is false
  fun 1: true
  4: a2 equals b1 is true
  fun 2: false
  5: b1 equals a1 is false
  fun 3: true
  6: b2 equals b1 is true
  fun 2: true
  7: b1 equals a4 is true
  </code></pre>
  
  <p>Thanks for the help!</p>