Java基础之值传递的一探究竟

Java方法签名中的参数被称为形参,而方法实际调用时传递到形参的值称为实参。Java的参数传递机制只有值传递,所谓值传递就会将实参的值副本传递到方法内,而参数本身不受到任何影响。比如:

示例一:

public class Test {
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        conver(a,b);
        System.out.println("a = "+String.valueOf(a)+ ";b = "+String.valueOf(b));
    }

    public static void conver(int a,int b){
        a=3;
        b=4;
        System.out.println("重新赋值后:a = "+String.valueOf(a)+ ";b = "+String.valueOf(b));
    }
}

打印结果:
重新赋值后:a = 3;b = 4
a = 1;b = 2

示例一中,a和b是conver方法的形参,main方法调用conver传入的实参a=1,b=2。conver方法中重新给参数赋值a=3,b=4,根据打印结果来看,a和b的值只是在conver方法中发生了变化,而实际传递的值未发生变化,这也证明了Java方法的传递机制。 

示例二:

public class Test2 {
    public static void main(String[] args) {
        User user = new User();
        user.age = 18;
        user.name = "hh";
        conver(user);
        System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
    }

    public static void conver(User user) {
        user.age = 20;
        user.name = "xx";
        System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
    }

    public static class User {
        int age;
        String name;
    }
}

//打印结果
age = 20;name = xx
age = 20;name = xx

示例二中,conver方法中形参为引用对象user,从打印结果中看出,修改user的值后发现user值的发生了变化。这好像又不符合Java的参数传递机制。

两种不同类型的参数传递,同样的操作对于参数本身却有不同的效果。究其原因是因为两个参数在初始化存储位置不同和运行时不同导致。两种参数一种是基本数据类型,一种是引用类型。在Java基础—类变量、实例变量、局部变量一种文中,局部变量随着进入方法、构造器、代码块时被创建,退出时被销毁这里传入方法内的确切应该是指变量的一个副本。根据JVM的运行原理,在方法入栈的时,变量的副本也会在栈中创建。基本数据类型,创建的是变量本身值的副本,而引用数据类型创建的是引用的副本。来看下下面的两个流程图:

一、基本数据类型:

基本数据类型

二、引用数据类型: 

引用数据类型

 

从图中可以看出,基本数据类型修改参数值是直接修改方法栈中的副本值,参数对象本身没有变化。而引用数据类型修改的参数,因对象引用最终指向的都是堆中的真正的对象空间,所以在方法内修改引用类型参数,参数本身也发生了变化。对示例二代码中稍作修改,消除对象引用关系,而对象值也会发生变化,这也证明了,参数为引用数据类型时,入栈的确实也是副本数据,不过不是参数本身的副本而是参数引用的副本,结合引用对象在堆中创建,参数为引用数据类型时也符合Java值传递的机制。

public class Test2 {
    public static void main(String[] args) {
        User user = new User();
        user.age = 18;
        user.name = "hh";
        conver(user);
        System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
    }

    public static void conver(User user) {
        user.age = 20;
        user.name = "xx";
        System.out.println("age = " + String.valueOf(user.age) + ";name = " + user.name);
        user = null;
    }

    public static class User {
        int age;
        String name;
    }
}

//打印结果
age = 20;name = xx
age = 20;name = xx

 关联扩展:

Java基础—类变量、实例变量、局部变量

一文了解JVM内存分配

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值