Creation date:


Overloading is one of the main feature of Java language. When class has overloaded methods, compiler has to determine which method will be run. Overloading in conjuction with autoboxing and var-args gets hard to understand.

class A {
   static void go(long i){
   static void go(Integer i){
   static void go(int... i){
   static void go(Integer i, Integer k){
      System.out.println("Integer, Integer");
   static void go(Object i){
   public static void main(String[] args) {
      int k=900;
      short s = 100;
      go(new Short(s));
      go(new Short(s), new Short(s));

This example is quite tricky because I joined several exceptional cases in one class. First look at result and try to understand, what's going on.

Integer, Integer

Now let's explain every line in output and validate the behaviour of compiler.

First we call go() with a primitive int argument. As you see we don't have go() method with int parameter. It may seem, that the method with Integer parameter will be applied. But it's not the case. Java first looks for wider primitive type, then for wrapper class. If we delete the go(long i) method, go(Integer i) will be applied instead. Explanation is obvious. Because widening capability existed before wrapper classes, preexisting codes should function the same way as before Java 5, designers made decision to choose widening over boxing. Widening beats boxing.

On second line we get Integer, Integer as the result of call go(k,k). Here we see, that both int arguments wrapped to Integer and go(Integer, Integer) method is called, although we have go(int...) method. It means boxing beats var-args. The reason is the same as in first case, compiler chooses older style to make decision. Widening also beats var-args. If we add go(long i, long j) method and call go(k,k) it'll call go(long i, long j) instead of go(int...).

In third case arguments match the parameter of go(int...) method without any boxing.

On fourth call go(new Short(s)); compiler widens Short to Object, because it can't widen it to Integer. Remember that all numeric wrappers are extend Numeric, but not each other.

On last call both Short objects are unboxed to short, then widened to int and go(int...) is called.

Author: Jafar N.Aliyev (Jsoft)

Read also

Static methods can not be overriden

Here I explain, why static methods can not be overriden

Use instanceof carefully

Usage of 'instanceof' method in some situations will give you a compilation error

Java access and nonaccess modifiers

Look at this cheat sheet for Java access and nonaccess modifiers

© Copyright

All articles in this site are written by Jafar N.Aliyev. Reproducing of any article must be followed by the author name and link to the site of origin(this site). This site also keeps the same rules relative to the articles of other authors.