Creation date:
Overloading
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){
System.out.println("long");
}
static void go(Integer i){
System.out.println("Integer");
}
static void go(int... i){
System.out.println("int...");
}
static void go(Integer i, Integer k){
System.out.println("Integer, Integer");
}
static void go(Object i){
System.out.println("Object");
}
public static void main(String[] args) {
int k=900;
short s = 100;
go(k);
go(k,k);
go(k,k,k);
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.
long
Integer, Integer
int...
Object
int...
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.