&. |

A software developer’s musings on software development

Java overload

Warning: I wrote this blog in 2007. That is a long time ago, especially on the internet. My opinions may have changed since then. Technological progress may have made this information completely obsolete. Proceed with caution.

Something I learned today: overloaded method resolution in Java is done at compile-time, not runtime. Warning: if you have no idea what half the words in that sentence meant, then you probably don’t care about the rest of this post.

Let’s say Alice (who is in tons of hacking books for some reason) wrote this code:

public class Alice
{
  public static long roundToNearestFive(long n)
  {
    return Math.round(n / 5.0) * 5L;
  }
}

And let’s say Bob (who totally has a thing for Alice even though she says they are just friends) wrote this code:

public class Bob
{
  public static void main(String[] args)
  {
    System.out.println(Alice.roundToNearestFive(12.7);
  }
}

When Bob runs his code it will print 10, since 12.7 will be silently converted to an integer (12) to be passed into roundToNearestFive(), and 12 is closer to 10 than to 15. Bob could call roundToNearestFive( Math.round(12.7)) to fix this, but that is annoying because now he has to first round his floating-point numbers before passing them into a rounding function. So Bob asks Alice to provide a fix, and she adds a version of the function which takes a floating-point number:

public class Alice
{
  public static long roundToNearestFive(long n)
  {
    return Math.round(n / 5.0) * 5L;
  }
  public static long roundToNearestFive(double d)
  {
    return Math.round(d / 5.0) * 5L;
  }
}

She sends a new .jar file to Bob with the change, and he runs his code again, expecting it to now output 15. But it still prints 10.

The problem is that when Bob compiled his code, there was no roundToNearestFive(double) function available. So the compiler generated bytecode that looked something like Parent.roundToNearestFive( (long)12.7). So even when he runs with Alice’s new code in place, the bytecode is still forced to call the integer version of the function. The only solution for Bob is to recompile his code against the new .jar file sent from Alice.

For further reference, here is the spec for binary compatibility in Java. And here is more information about Alice and Bob.