下面的程序很好的演示了静态分配的含义(可以先试一下运行结果)
package....
/*静态方法分配(分配这个词并不好,因为dispatch并不运用到静态环境之中)演示*/
public class StaticTest{
static abstract class Fruit{}
static class Apple extends Fruit{}
static class Orange extends Fruit{}
public void eat(Fruit raw){
System.out.println("Oh !!! Fruit is raw");
}
public void eat(Orange raw){
System.out.println("Oh !!! Orange is raw");
}
public void eat(Apple raw){
System.out.println("Oh !!! Apple is raw");
}
public static void main(string[] args){
Fruit app = new Apple();
Fruit oran = new Orange();
StaticTest ts = new StaticTest();
System.out.println(ts.eat(app));
System.out.println(ts.eat(oran));
}
}
Fruit app = new Apple();
其中的Fruit成为是静态类型(static Type),也叫外观类型,而Apple称为是变量的实际类型,静态类型的变化仅仅在使用过程中发生,变量本身的静态类型不会发生变化,并且最终静态类型是在编译期可知的。而实际类型变化的结果在运行期才可以确定,编译器在编译程序的时候并不知道一个对象的实际类型是什么
在代码中,可以定义了两个静态类型相同,但实际类型不同的变量,但是编译器重载是通过参数的静态类型(上面说过实际类型运行期才可见),静态类型编译期是可知的,因此在编译阶段,javac编译器会根据参数的静态类型决定重载那个版本。
//运行结果
Oh!!! fruit is raw
Oh!!! fruit is raw
所以由静态类型来定位方法执行版本的分派动作称为静态分配,静态分配发生在编译阶段,实际上是由编译器完成的,并不是由虚拟机完成。