Java之值传递还是引用传递

Java中是值传递还是引用传递

1,形参与实参

形式参数: 是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。

实际参数: 在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”

    public static void main(String[] args) {
        int[] arr = {2,23,55,88,90,100};
        int search = search(arr, 55);//实参
        System.out.println(search);
    }

    public static int search(int[] arr,int x){//数组arr和x为形参
        int low = 0;
        int high = arr.length-1;
        while (low<=high){
            int mid = low + (high-low)/2;
            if (arr[mid]==x){
                return mid;
            }else if (arr[mid]<x){
                low = mid+1;
            }else {
                high=mid-1;
            }
        }
        return -1;
    }

2,值传递与引用传递

值传递:指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递:指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。

3,java中的传递类型

3.1 基本数据类型

测试代码:

public class Test {
    public static void change(int i) {
        i = 99;
    }
    public static void main(String[] args) {
        int i = 66;
        System.out.println("修改之前,i的值:" + i);
        change(i);
        System.out.println("修改之后,i的值:" + i);
    }
}

输出结果:

在这里插入图片描述

由结果可以看出,在调用change()方法时,会复制实参i的值66并传递给形参i。然后,再对形参i进行赋值i=99。随着change()方法的结束,形参i的生命周期也会跟着结束。

3.2 引用数据类型

User类:

/**
 * @Author
 * @Date
 * @Version v1.0
 * @Description
 */
public class User {
    private String name;
    private  int age;

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public User() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

测试类:

public class test {
    public static void main(String[] args) {
        User user = new User("小王",24);
        System.out.println("修改之前,user的值:" + user.getName()+user.getAge());
        System.out.println("修改之前,实参user的hashCode的值:" + user.hashCode());
        change(user);
        System.out.println("修改之后,user的值:" + user.getName()+user.getAge());
        System.out.println("修改之后,实参user的hashCode的值:" + user.hashCode());
    }
    public  static void change(User user){
        System.out.println("形参user的hashCode的值:" + user.hashCode());
        user.setName("小虎");
        user.setAge(22);

    }
}

输出结果:
在这里插入图片描述

由结果可以看出,形参和实参的hasCode值一样,表明是相同的对象。说明在调用change()方法时,先获取实参user的内存地址,再把实参user内存地址的值传递给形参user。

将测试类中的change方法修改:


    public  static void change(User user){
        user = new User();
        System.out.println("形参user的hashCode的值:" + user.hashCode());
        user.setName("小虎");
        user.setAge(22);

    }

输出结果:
在这里插入图片描述

由结果可以看出,实参和形参的hasCode值不一样,表明是不同的对象;最后实参user的name属性也没有被修改。

说明: Java中的对象传递,如果是修改引用,是不会对原来的对象有任何影响的,但是如果直接修改共享对象的属性的值,是会对原来的对象有影响的。

3.3 String数据类型

测试代码:

public class test {

    public static void change(String s) {
        System.out.println("形参s的hashCode的值:" + s.hashCode());
        s = "Leon";
        System.out.println("修改之后,形参s的hashCode的值:" + s.hashCode());
    }

    public static void main(String[] args) {
        String s = new String("wangerhei");
        System.out.println("修改之前,s的值:" + s);
        System.out.println("修改之前,实参s的hashCode的值:" + s.hashCode());
        change(s);
        System.out.println("修改之后,s的值:" + s);
        System.out.println("修改之后,实参s的hashCode的值:" + s.hashCode());
    }

}

输出结果:
在这里插入图片描述

由结果看出,调用change()方法前后,实参s所指向的内容并没有改变,但是hasCode值却改变了。是因为:字符串是一个特殊的数据类型,它的底层是一个final 型的ch[]数组,被final修饰的变量是无法改变的,所以字符串在作为参数传递时,可以当作对一个特殊的数组进行操作。同样地,在调用change()方法时,先获取实参s的内存地址,再把实参s内存地址的值传递给形参s。(两者的HashCode值一样)。但是经过 s = "Leon";操作,由于字符串的不可变性,会new一个新的字符串对象wzc,由形参s指向这个新对象的内存地址。所以,形参s的hasCode值会发生变化。但是随着change()方法的结束,形参s的生命周期也会跟着结束。所以最后实参s的hashCode值是一样的。

4,案例分析

结合上面的案例分析:为什么java中只有值传递

1,基本数据类型:从上面的例子看到,当时传递的是基本数据类型时,我们是会复制实参i的值66并传递给形参i,改变形参时不会影响实参原来的值,符合值传递的条件。

2,引用数据类型:针对上面的例子,我们可以看到Uer的属性,比如姓名会发生改变(这时大多数人会认为是引用传递),但其实我们传递引用数据类型时,我们复制的是引用类型的地址。change方法改变引用类型的属性值,是不会影响到引用类型的地址,所以引用数据类型(user对象)来说地址才是实参。但是第二个测试,在change()方法中修改user引用的地址,即新创建一个新的user对象的话,就会看到main方法中的user并没有任何改变,也就反向印证了它实际上是值传递。

3,String数据类型:String类型变量自然也是将String类型变量引用拷贝一份传递给change()方法,根据值传递的定义,函数对这个副本的修改不会影响到实际参数,又因为String的final特性,实际上就是修改了String类型变量地址,因此,实际参数不会受函数修改的影响。

所以,综上所述, java中只有值传递没有引用传递!!!

作者:王二黑_Leon
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
本文章仅作为自学所用。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

王小二_Leon

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

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

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

打赏作者

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

抵扣说明:

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

余额充值