java里的五大invoke指令分别是invokespecial、invokevirtual、invokestatic、invokeinterface、invokedynamic。
静态方法的调用,生成的是invokestatic指令。
接口方法的调用,生成的是invokeinterface指令。
其他的方法,区别在于非final的方法生成invokevirtual指令,这是java保证多态的关键。final方法则生成invokespecial指令。
最复杂的当属于invokedynamic指令了,其目的是实现动态类型。众所周知,java是一种动态类型语言。举个例子,python可以这样写代码:
class A: def print(self): print('A') class B: def print(self): print('B') if __name__ == '__main__': # 取命令行参数 print(A()) print(B())
如果换成java,这两个类就必须实现同一个接口。但是现在java也可以了。lambda表达式就是这种代码。这个指令底层依靠methodhandle来实现,其实现原理超级复杂。但简而言之,就是把callsite传给invokedynamic指令,从call site中找到bootstrap method来调用真正的方法。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)