Let's assume I have following code:
// Method acception generic parameter
public static <T> T foo(T para) {
return para;
}
// Method accepting Integer parameter
public static Integer foo(Integer para) {
return para + 1;
}
// Method accepting Number parameter
public static Number foo(Number para) {
return para.intValue() + 2;
}
public static void main(String[] args) {
Float f = new Float(1.0f);
Integer i = new Integer(1);
Number n = new Integer(1);
String s = "Test";
Number fooedFloat = foo(f); // Uses foo(Number para)
Number fooedInteger = foo(i); // Uses foo(Integer para)
Number fooedNumber = foo(n); // Uses foo(Number para)
String fooedString = foo(s); // Uses foo(T para)
System.out.println("foo(f): " + fooedFloat);
System.out.println("foo(i): " + fooedInteger);
System.out.println("foo(n): " + fooedNumber);
System.out.println("foo(s): " + fooedString);
}
The output looks the following:
foo(f): 3
foo(i): 2
foo(n): 3
foo(s): Test
Now the question(s):
foo(n)callsfoo(Number para), most probably becausenis defined asNumber, even though it has anIntegerassigned to it. So am I right in the assumption that the decision, which of the overloaded methods is taken happens at compile-time, without dynamic binding? (Question about static and dynamic binding)foo(f)usesfoo(Number para), whilefoo(i)usesfoo(Integer para). Onlyfoo(s)uses the generic version. So the compiler always looks if there is a non-generic implementation for the given types, and only if not it falls back to the generic version? (Question about generics)- Again,
foo(f)usesfoo(Number para), whilefoo(i)usesfoo(Integer para). Yet,Integer iwould also be aNumber. So always the method with the "outer-most" type within the inheritance tree is taken? (Question about inheritance)
I know these are a lot questions, and the example is not taken from productive code, yet I just would like to know what "happens behind" and why things happen.
Also any links to the Java documentation or the Java specification are really appreciated, I could not find them myself.