Consider the following two Java classes:
a.) class Test { void foo(Object foobar) { } }
b.) class Test { void foo(pkg.not.in.classpath.FooBar foobar) { } }
I created two classes : Caller and Callee
public class Caller {
public void doSomething( Callee callee) {
callee.doSomething();
}
public void doSame(Callee callee) {
callee.doSomething();
}
public void doSomethingElse(Callee callee) {
callee.doSomethingElse();
}
}
public class Callee {
public void doSomething() {
}
public void doSomethingElse() {
}
}
I compiled these classes and then disassembled them with javap -c Callee > Callee.bc and javap -c Caller > Caller.bc. This produced the following:
Compiled from "Caller.java"
public class Caller extends java.lang.Object{
public Caller();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public void doSomething(Callee);
Code:
0: aload_1
1: invokevirtual #2; //Method Callee.doSomething:()V
4: return
public void doSame(Callee);
Code:
0: aload_1
1: invokevirtual #2; //Method Callee.doSomething:()V
4: return
public void doSomethingElse(Callee);
Code:
0: aload_1
1: invokevirtual #3; //Method Callee.doSomethingElse:()V
4: return
}
Compiled from "Callee.java"
public class Callee extends java.lang.Object{
public Callee();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."":()V
4: return
public void doSomething();
Code:
0: return
public void doSomethingElse();
Code:
0: return
}
The compiler generated a method signature and a typesafe invokevirtual call for the method calls to 'callee' - it knows what class and what method is being invoked here. If that class wasn't available, how would the compiler generate the method signature or the `invokevirtual'?
There is a JSR (JSR 292) to add an 'invokedynamic' opcode that would support dynamic invocation, however this isn't currently supported by the JVM.