JAVA方法传参分析

Java只有值传递, 结论 大家都很清楚了.

么java将方法的实参传递给形参 具体是怎么做的呢? 

 

下面先定义一个测试类Tese  里面只有一个fun方法
public class Test {
    void fun(int i){
        int b =i;
    }
    public static void main(String[] args) {
        new Test().fun(4);
    }
}
 
我们使用 jclasslib工具查看一下fun()函数对应的  局部变量表(本地标量表) 有3个变量
 
分别是;
this : this 是自动添加的.里面的值是当前对象的引用
i :形参
b:内部的局部变量
 
查看一下 fun()函数对应的字节码 
如下图
 
0 iload_1 #以读取整数的形式去读取 局部变量表 下标为1的变量的值并压入到操作数栈
1 istore_2 #把操作数栈 栈顶的数值  赋值给 局部变量表下标为2的变量
2 return  # 返回结束函数调用
 
从上面的字节码可以得知 
做的操作只是 把i的值复制给b. 已经完成了把常量4 赋值给形参i的 传值操作
传参操作并没在被调用函数的字节码里面明文显示,
那我们现在返回去看一下调用函数 main() 做了那些操作 是不是可能传参操作在调用函数里面.
 
main()函数字节码如下
0 new #2 <Test>  #创建一个Test 类的对象
3 dup             #复制操作数栈顶值,并将其压入栈顶,也就是说此时操作数栈上有连续相同的两个对象地址
4 invokespecial #3 <Test.<init>> #调用实例初始化方法<init>:()V
7 iconst_4  #把常数 4 压入到操作栈中
8 invokevirtual #4 <Test.fun> #传参操作在这条指令
11 return   # 返回结束函数调用
 
 
invokevirtual  命令
 
    在官方文档中这样描述:
 
     假设objectref的类型为C,实际调用的方法将按照下面流程来查找:
  • 如果C包含了一个方法m的声明,该声明重写了解析出来的方法,则m为实际调用的方法,查找终止。
  • 否则:如果C有父类,则自下而上递归的在C的直接父类中执行第一步的查找。
  • 如果还没有查找到,则抛出AbstractMethodError错误。
如果解析出来的方法有参数的话,在操作数栈上,所有的参数的值必须按照方法描述中规定的数量,类型和顺序自上而下跟在objectref后面。
而且如果解析出来的方法不是native的,所有的参数和objectref从操作数栈中弹出。在JVM栈上为当前准备调用的方法创建一个新的栈帧。
Objectref和所有参数被按照如下顺序作为新栈帧的局部变量,objectref占slot0,arg1占slot1(否则,如果arg1为long或double类型,则占slot1和slot2),以此类推。对于float类型参数,在存入局部变量表之前会先进行值集转换。新的栈帧成为当前栈帧,JVM的PC设置为即将调用方法的第一条指令的操作码,程序执行从第一条指令继续进行。
 
由此可以得知java传参操作 发生在主调代码块.由命令  invokevirtual  实现
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值