Java编译器的行为------第一节:方法

可以将Java虚拟机看做一个组件,他的存在实现了Java程序“一次编译,到处执行”的目标。Oracle的JDK软件包含两部分内容:一部分是将Java源代码编译成字节码文件(Java虚拟机指令集文件)的编译器,一部分是用于实现Java虚拟机运行时环境(JRE)。编译器和虚拟机两者相辅相成,下面是Java编译器的行为:


1、接收参数

如果传递n个参数给某个实例方法,则当前栈帧会按照约定的顺序接收这些参数,并将它们保存在方法的第1个到第n个局部变量之中,而他的第0个局部变量用于存放自身实例的引用(Java语言中访问自身实例的关键字this就是通过第0个局部变量实现的)。

如果传递n个参数给一个类方法(static),则当前栈帧也会按照约定的顺序接收这些参数,但将它们保存在方法的第0个到第n-1个局部变量之中(因为类方法不依赖于实例,不存在自身实例引用这一概念)。

2、方法调用

普通实例方法调用是在运行时根据对象类型进行分派的(相当于动态绑定),这类方法的调用是通过虚拟机指令集中的invokevirtual指令完成,该指令带有一个表示索引的参数,该参数表示此方法的符号引用在运行时常量池中的索引位置,通过符号引用就可以获得方法所在对象类型的名称、方法名称和方法描述符。

注:编译器并不需要获得类实例的内部布局,他只需产生方法的符号引用并存储到常量池中即可。而运行时常量池项会在执行时转换成调用方法的实际地址。

类方法(static)调用过程和普通实例调用方法类似,区别在两个方面:类方法调用是通过虚拟机指令集中的invokestatic指令完成;类方法调用时无需传递this参数。

实例初始化方法是有编译器调用的,其调用是通过虚拟机指令集中的invokespecial指令完成。同时,父类的实例方法和实例的私有方法调用也是通过invokespecial指令完成。

注:使用invokespecial指令的方法都是实例方法,故其第0个局部变量都为this。

注:编译器在生成invokevirtual指令时,也会生成这个指令所引用的描述符,这个描述符包含方法实际参数和返回类型。编译器在方法调用时不会处理参数的类型转换问题,只是简单的将参数压人操作数栈,且不改变其类型。而对于描述符的解析要等到运行时才会进行。






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我叫白小猿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值