Java中只存在值传递

Wesley13
• 阅读 907

在Java中并不存在引用传递(即地址传递),对于变量(可以是基本数据类型,也可以是引用数据类型)而言,可以理解为就是一个地址。传递,存在着拷贝操作。举个列子:

1、在方法参数上,传递的是基本数据类型。
定义了一个用于交换两个整型数的方法:

public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
        System.out.println("In swap: a = " + a + ", b = " + b);
    }

在main方法里初始化两个整型变量,并调用swap方法:

public static void main(String[] args) {
        int a = 1;
        int b = 2;
        
        System.out.println("Before swap: a = " + a + ", b = " + b);
        swap(a, b);
        System.out.println("After swap: a = " + a + ", b = " + b);
    }

注:假设实参a为0x0001,实参b为0x0002。它们所指向的值分别为1和2。
Java中只存在值传递

输出结果为:

Before swap: a = 1, b = 2

In swap: a = 2, b = 1

After swap: a = 1, b = 2

注:调用swap方法时,由于是值传递,所以可以假设形参a为0x0003,形参b为0x0004。这时实参a和b将自己所指向的值拷贝了一份。根据调用的方法参数列表与声明的方法参数列表一一对应的顺序,这时0x0003所指向的值是1,0x0004所指向的值是2。对应值传递这个概念,这时拷贝的是值1和2。
Java中只存在值传递
对于swap方法的作用是指将0x0003和0x0004所指向的值进行了交换。即0x0003所指向的值变成了2,而0x0004所指向的值变成了1。所以对于实参a和b来说并不受影响。 
Java中只存在值传递
如果真的存在引用传递的话,这时候形参的值是地址,即拷贝的是0x0001和0x0002。
Java中只存在值传递
交换作用就会反映到实参a和b上。
Java中只存在值传递

2、在方法参数上,传递的是引用数据类型。

这里以Person类为例:

class Person {
    private String name;
    
    public Person(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "My name is " + this.name + ".";
    }
}

同样,定义一个swap方法,用于交换两个引用数据类型:

public static void swap(Person c, Person d) {
        Person temp = null;
        temp = c;
        c = d;
        d = temp;
        System.out.println("In swap: " + c + ", " + d);
    }

在main方法里初始化两个Person类型的引用,并调用swap方法:

public static void main(String[] args) {
        Person c = new Person("c");
        Person d = new Person("d");

        System.out.println("对于引用数据类型");
        System.out.println("Before swap: " + c + ", " + d);
        swap(c, d);
        System.out.println("After swap: " + c + ", " + d);
    }

注:假设实参c为0x0001,实参d为0x0002。它们有各自引用的对象0x000c和0x000d。它们是对象在堆区里的存放地址。
Java中只存在值传递

输出结果为:

对于引用数据类型
Before swap: My name is c., My name is d.
In swap: My name is d., My name is c.
After swap: My name is c., My name is d.

注:调用swap方法时,由于是值传递,所以可以假设形参c为0x0003,形参d为0x0004。根据调用的方法参数列表与声明的方法参数列表一一对应的顺序,这时形参c(0x0003)所引用的就是实参c(0x0001)所引用的对象, 形参d(0x0004)所引用的就是实参d(0x0002)所引用的对象 。 对应值传递这个概念,这时拷贝的是0x000c和0x000d。
Java中只存在值传递
此时swap方法的作用是指将0x0003和0x0004对对象的引用进行了交换。
Java中只存在值传递
如果真的存在引用传递的话,这时候拷贝的是0x0001和0x0002。
Java中只存在值传递
交换作用就会反映到实参c和d上。
Java中只存在值传递
注:变量是存放在栈区的,而对象是存放在堆区的。

引用数据类型值传递的图解:
1、swap调用前:
Java中只存在值传递
2、调用swap的时候:
Java中只存在值传递
3、swap方法执行完后:
Java中只存在值传递
4、swap调用后:
Java中只存在值传递

完整的实例程序代码如下:

package com.test;

public class Test {
    public static void swap(int a, int b) {
        int temp = a;
        a = b;
        b = temp;
        System.out.println("In swap: a = " + a + ", b = " + b);
    }
    
    public static void swap(Person c, Person d) {
        Person temp = null;
        temp = c;
        c = d;
        d = temp;
        System.out.println("In swap: " + c + ", " + d);
    }
    
    public static void main(String[] args) {
        int a = 1;
        int b = 2;
        Person c = new Person("c");
        Person d = new Person("d");
        
        System.out.println("对于基本数据类型");
        System.out.println("Before swap: a = " + a + ", b = " + b);
        swap(a, b);
        System.out.println("After swap: a = " + a + ", b = " + b);
        
        System.out.println("对于引用数据类型");
        System.out.println("Before swap: " + c + ", " + d);
        swap(c, d);
        System.out.println("After swap: " + c + ", " + d);
    }
}

class Person {
    private String name;
    
    public Person(String name) {
        this.name = name;
    }
    
    @Override
    public String toString() {
        return "My name is " + this.name + ".";
    }
}

总结:
1、Java中只存在值传递,并不存在引用传递。
2、若形参引用修改了所引用的对象的状态,则也会反映到实参引用上。

点赞
收藏
评论区
推荐文章
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Wesley13 Wesley13
3年前
java传值与引用的关系
       首先,我们必须要搞清楚的一件事是,不管java的参数类型是什么,一律传递的是参数的副本。也就是说每次传递参数的时候都会讲参数拷贝一份传递。1.基本数据类型:       对于基本的数据类型来说,java传递的是指的副本;也就是将数据拷贝一份以后传递。因此当函数返回的时候,不管在调用的函数中做了什么操作,基本数据类型的值都不会改变。
Wesley13 Wesley13
3年前
Java对象的浅拷贝和深拷贝&&String类型的赋值
Java中的数据类型分为基本数据类型和引用数据类型。对于这两种数据类型,在进行赋值操作、方法传参或返回值时,会有值传递和引用(地址)传递的差别。浅拷贝(ShallowCopy):①对于数据类型是基本数据类型的成员变量,浅拷贝会直接进行值传递,也就是将该属性值复制一份给新的对象。因为是两份不同的数据,所以对其中一个对象的该成员变量值进行修改,
Wesley13 Wesley13
3年前
Java中==和equals的区别
""可以比较基本数据类型,也可以比较引用数据类型。如果比较基本数据类型比较的是变量中存储的值;如果比较引用类型比较的是变量中存储的地址引用。equals()是Object类中继承过来的方法,每个引用类型都可以调用,默认继承的equals()方法的比较与""一致。如下代码所示: publicbooleanequals(Objectobj)
Wesley13 Wesley13
3年前
Java里的按值传递与引用传递
按值传递还是按引用传递这个在Java里面是经常被提起的问题,也有一些争论,似乎最后还有一个所谓的结论:“在Java里面参数传递都是按值传递”。事实上,这很容易让人迷惑,下面先分别看看什么是按值传递,什么是按引用传递,只要能正确理解,至于称作按什么传递就不是个大问题了。1:按值传递是什么指的是在方法调用时,传递的参
Wesley13 Wesley13
3年前
Java到底是引用传递还是值传递
前言前段时间在群里看到类似这样一个问题,下面的代码会输出什么呢?public void test(){   String str  "hello";   change(str);   System.out.println(str);}private void change(String str){  
Wesley13 Wesley13
3年前
Java只有值传递(Java值传递还是引用传递?)
转载请注明原文地址:https://www.cnblogs.com/ygj0930/p/10830521.html(https://www.oschina.net/action/GoToLink?urlhttps%3A%2F%2Fwww.cnblogs.com%2Fygj0930%2Fp%2F10830521.html)一:区分Java数据类型、变
Stella981 Stella981
3年前
JVM调优总结一
数据类型   Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象本身,对象本身存放在这个引用值所表示的地址的位置。基本类型包括:byte,short,int,long,cha
Wesley13 Wesley13
3年前
Java面试中的值传递与引用传递
一、前言Java是值传递的,对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。对于对象型变量而言的,传递的是该对象地址的一个副本,,并不是原对象本身,这里也有人说是引用传递。由于副本的地址和原对象地址一致,因此对副本的值进行操作时,会同步改变原对象值。_但是一旦副本的地址被改变,副本的值的操作则不会影响原对象地址。(
Easter79 Easter79
3年前
Swift3.0 类和结构体的选择
结构体实例总是通过值传递,类实例总是通过引用传递先说说值类型和引用类型的区别值类型被赋予给一个变量、常量或者被传递给一个函数的时候,其值会被拷贝在Swift中,所有的结构体和枚举类型都是值类型。这意味着它们的实例,以及实例中所包含的任何值类型属性,在代码中传递的时候都会被复制。引用类型在被赋予到一个变量、常