Java学习

Java中,只有按值传递
看这一篇就够了:https://blog.csdn.net/javazejian/article/details/51192130

更新:
首先,什么是按值传递和按引用传递?
值传递: 在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
引用传递: 指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
从技术上讲,Java 总是按值传递,引用对象的传递其实还是将实参拷贝一份给形参。之所以修改形参可以修改到实参,是因为修改的是同一块地址。若是new了一个新对象,并赋给形参,则实参跟形参就互不影响了,如果是引用传递,实参也会指向新对象!!!

参考:https://juejin.cn/post/7023016680024440863

1. java中的值传递和引用传递

对象传递(数据、类、接口) 是引用传递,原始类型数据(整型、浮点型、字符型、布尔型)传递是值传递。

值传递:传递对象的一个副本,即使副本被改变,也不会影响源对象,因为值传递的时候,实际上是将实参的值复制一份到形参。
引用传递:传递的并不是实际的对象,而是对象的引用,外部对引用对象的改变也会反映到源对象上,因为引用传递的时候,实际上是将实参的地址复制一份到形参

2. 示例

示例1(值传递)

package com.zwwhnly.springbootaction;

public class ArrayListDemo {

    public static void main(String[] args) {
        int num1 = 10;
        int num2 = 20;

        swap(num1, num2);

        System.out.println("num1 = " + num1);
        System.out.println("num2 = " + num2);
    }

    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;

        System.out.println("a = " + a);
        System.out.println("b = " + b);
    }
}

运行结果:

a = 20
b = 10
num1 = 10
num2 = 20

可以看出,虽然在swap()方法中a,b的值做了交换,但是主方法中num1,num2的值并未改变。

示例2(引用类型传递):

package com.zwwhnly.springbootaction;

public class ArrayListDemo {

    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4, 5};

        change(arr);

        System.out.println(arr[0]);
    }

    public static void change(int[] array) {
        System.out.println(array[0]);
        array[0] = 0;
    }
}

运行结果:

1
0

可以看出,在change()方法中将数组的第一个元素改为0,主方法中数组的第一个元素也跟着变为0。

示例3(StringBuffer类型):

package com.zwwhnly.springbootaction;

public class ArrayListDemo {

    public static void main(String[] args) {
        StringBuffer stringBuffer = new StringBuffer("博客园:申城异乡人");
        System.out.println(stringBuffer);

        changeStringBuffer(stringBuffer);
        System.out.println(stringBuffer);
    }

    public static void changeStringBuffer(StringBuffer stringBuffer) {
        stringBuffer = new StringBuffer("掘金:申城异乡人");

        stringBuffer.append(",欢迎大家关注");
    }
}

运行结果:

博客园:申城异乡人
博客园:申城异乡人

也许你会认为第2次应该输出“掘金:申城异乡人,欢迎大家关注”,怎么输出的还是原来的值呢,那是因为在changeStringBuffer中,又new了一个StringBuffer对象,此时stringBuffer变量指向的内存地址已经改变,所以主方法中的stringBuffer变量未受到影响

如果修改changeStringBuffer()方法的代码为:

public static void changeStringBuffer(StringBuffer stringBuffer) {

    stringBuffer.append(",欢迎大家关注");
}

则运行结果会变为:

博客园:申城异乡人
博客园:申城异乡人,欢迎大家关注

示例4(String类型):

package com.zwwhnly.springbootaction;

public class ArrayListDemo {

    public static void main(String[] args) {
        String str = new String("博客园:申城异乡人");
        System.out.println(str);

        changeString(str);
        System.out.println(str);
    }

    public static void changeString(String string) {
        //string = "掘金:申城异乡人";
        string = new String("掘金:申城异乡人");
    }
}

运行结果:

博客园:申城异乡人
博客园:申城异乡人

在changeString()方法中不管用string = “掘金:申城异乡人”;还是string = new String(“掘金:申城异乡人”);,主方法中的str变量都不会受影响,也验证了String创建之后是不可变更的。

示例5(自定义类型):

package com.zwwhnly.springbootaction;

public class Person {
    private String name;

    public String getName() {
        return name;
    }

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

    public Person(String name) {
        this.name = name;
    }
}
package com.zwwhnly.springbootaction;

public class ArrayListDemo {

    public static void main(String[] args) {
        Person person = new Person("zhangsan");
        System.out.println(person.getName());

        changePerson(person);
        System.out.println(person.getName());
    }

    public static void changePerson(Person p) {
        Person person = new Person("lisi");
        p = person;
    }
}

运行结果:

zhangsan
zhangsan

未改变源值的原因,仍然是person是新new的,p指向了新的地址,从而不会影响源值
修改changePerson()方法代码为:

public static void changePerson(Person p) {
    p.setName("lisi");
}

则运行结果为:

zhangsan
lisi

这里p没有指向新地址,而只是更改了对象属性,所以影响源值
个人理解:引用传递,实际上就是将实参的地址复制一份到形参,如果不更改地址的指向,对其修改,就会影响源值,如果指向了其他地址,再对其修改,就不会影响到源值。String是个例外,其赋值语句也可以看作是一个new操作(在字符串常量池重新new 了一个对象,即相当于更改了地址指向)。
java面试: https://www.cnblogs.com/zwwhnly/p/10826530.html
深入理解java String: https://www.cnblogs.com/xiaoxi/p/6036701.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值