1. 装载、连接、初始化

    Java的class文件,会在装载的时候,生成Class信息。缺失的符号,通过连接,变成直接引用。虽然我们都是对一个不存在的类发起引用的时候,发生类没有定义的异常,但是这并不意味着装载和连接一定是lazy模式的,只是标准规定了抛出异常的时机必须同lazy模式的时刻相同。

    初始化总是lazy的。


2. 类的私有方法

    类调用自己的私有方法,使用的是invokespecial,而不是invokevirtual。这意味着,调用私有方法不会查询对象的函数表,而只是使用调用者所在类的方法。这和Java的语法是一致的,私有方法不重载。


3. 构造方法

    调用类的构造方法,使用的是invokespecial <init>。特殊的,会检查第一句是不是super,如果是的话,先调用指定的父类的构造方法;如果是this,会调用其他构造方法;如果都不是,先调用无参的父类构造方法。

    Java会总是给没有显示声明构造方法的类,加一个默认的无参构造方法,这点和C++很不同。

    另一个不同是,构造方法里面调用公有方法,会查询函数符号表,选择重载后的函数调用。也就意味着,使用的是invokevirtual。这点和C++也不一样,C++即使声明了virtual关键字,由于构造的时候虚表没有建立起来,还是调用这个父类的方法。


4. 操作数和返回值

    Java是把操作数都存放在栈中,然后根据操作符需要多少个操作数,从栈里面取数进行运算。而不是使用寄存器,主要是出于跨平台的考虑。

    返回值是存放在临时变量中,这点很特殊。这意味着,如果在finally代码块指定了不同于try块和catch块指定的返回值,那么最终的返回值应该是finally代码块所指定的。


5. 类加载器

   正确的类加载器的实现,应该是优先从父加载器蹭蹭递归查找。但是程序员重载的类加载器可以不选择这样做,虽然大部分都应该遵循此规则。


6. 对象与接口的函数引用

   用类引用一个对象调用方法,和用接口引用一个对象调用方法,理论上开销是不同的,前者小一些。因为用类引用,函数表总是能够定下来的。总是可以直接把偏移替换掉函数名,即连接时查找。而接口则不同,需要用函数名匹配函数表,找到对应的偏移,进而得到函数代码段的地址,即运行时查找。