1 instance variables & instance function
对象f的引用类是Fahter,但实际指向的son对象。
JVM 调用类的instance variable时,会在编译期间就静态链接到对象引用类(Father)的字段。所以f的字段都是来自Father的字段。
JVM 调用类的instance variable时,会在运行期间就动态联接到实际运行类的方法,所以f的方法是基于实际运行类(只有运行时才知道的)来选择所调用的方法。
所以一般类的instance variable,会定义为private,通过set和get来操作。
2 class instance & class function
Parent Class
Son Class
Main Class
运行的结果:
JVM 调用类的class variable时,会在编译期间就静态链接到对象引用类(Father)的字段。所以f的字段都是来自Father的字段。
JVM 调用类的class variable时,会在编译期间就静态联接到对象引用类(Father)的方法,所以f的staitc方法是基于对象引用类(只有编译期间)来选择所调用的方法。
引用:
主函数中声明了对Parent的引用obj1,这个引用指向Son的对象,即实际对象是利用new Son()所创建的实例。
上例中,obj1对调用了Parent类的静态方法sayHello(),而调用了Son类的实例方法sayHello()。对类方法和实例方法调用的区别,《深入Java虚拟机》中有这样一段话可以解释:
引用
当JVM调用一个类方法时,它会基于对象引用的类型(通常在编译时可知)来选择所调用的方法。相反,当JVM调用一个实例方法是,它会基于实际对象的类(只能在运行时得知)来选择所调用的方法。
对象引用obj1的类型Parent自加载进入JVM之后便在内存的方法区维护了静态方法,而Son类的实例方法sayBye()是在被实际对象调用的时候才动态连接的。
基于上面分析可以推测,因为类在方法区中还维护了字段信息、类(静态)变量、常量池,JVM调用一个字段时,它将基于对象引用的类型来选择所调用的字段,故obj1调用的字段皆来自于父类Parent。
注:常量池:常量池就是该类型所用常量的一个有序集合,包括直接常量(string、integer和floating point常量)和对其他类型、字段和方法的符号引用。池中的数据项就像数组一样是通过索引访问的,因为常量池存储了相应类型所用到的所有类型、字段和方法的符号引用,所以他在java程序的动态连接性中起到核心作用。
Parent static fragment
Son Static Fragement
parent Constructor
Son Constructor
Parent static function
Son instance function
Parent
Parent variable
Parent Reference Object