Java中是值传递和引用传递

article/2025/9/12 23:12:06

值传递 / 引用传递
值传递:就是在方法调用的时候,实参是将自己的一份拷贝赋给形参,在方法内,对该参数值的修改不影响原来的实参。

引用传递:是在方法调用的时候,实参将自己的地址传递给形参,此时方法内对该参数值的改变,就是对该实参的实际操作。

Java中只有值传递
首先回顾一下在程序设计语言中有关将参数传递给方法(或函数)的一些专业术语。

按值调用(call by value):表示方法接收的是调用者提供的值。

按引用调用(call by reference):表示方法接收的是调用者提供的变量地址。

它用来描述各种程序设计语言(不只是 Java)中方法参数传递方式。

Java 程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,即,方法不能修改传递给它的任何参数变量的内容。

swap( ) 场景
要求写一个函数交换int类型的a和b的值

在 swap() 方法中,a、b 的值进行交换,并不会影响到 A、B。因为,a、b 中的值,只是从 A、B 复制过来的。也就是说,a、b 相当于 A、B 的副本,副本的内容无论怎么修改,都不会影响到原件本身。

如果我们这么写:

public class test{
  
    public static void main(String[] args) {
          int A = 2;
          int B = 3;
          swap(A, B);
        System.out.println(A);
        System.out.println(B);
    }
    
      public static void swap(int a, int b){
        int tmp = a;
        a = b;
        b = tmp;
        }
}


运行结果为:

2
3


发现A和B的值并没有交换,为什么呢?

因为Java中采用的是值传递,也就是说执行swap(int a, int b)时,这里的参数a和b,只是A和B的副本,函数的运行结果并没有改变原来A和B的值。

那么采用Integer呢?

如果将上面的int类型转变为Integer,swap(Integer a, Integer b)会不会实现交换功能呢?

public class test{
  
    public static void main(String[] args) {
          Integer A = 2;
          Integer B = 3;
          swap(A, B);
        System.out.println(A);
        System.out.println(B);
    }
    
      public static void swap(Integer a, Integer b){
        Integer tmp = a;
        a = b;
        b = tmp;
        }
}


运行结果为:

2
3


可见还是没有完成交换!

去查看Integer的源码:

public final class Integer extends Number implements Comparable<Integer> {}

可以看到Integer使用final修饰的int进行存储。final修饰的变量不能被重新赋值,所以操作参数传递变量时,实际上是操作变量对象的副本(Java中的包装类型都是默认使用这种方式实现的,使用拷贝副本的方式提升效率和减少内存消耗)。

如果换作是数组呢?

public static void main(String[] args) {
    int[] arr = { 1, 2, 3, 4, 5 };
    System.out.println(arr[0]);
    change(arr);
    System.out.println(arr[0]);
}

public static void change(int[] array) {
    // 将数组的第一个元素变为0
    array[0] = 0;
}


运行结果为:

1

0


这里方法array是对象的引用arr的拷贝,而不是对象本身的拷贝,因此, array 和 arr 指向的是同一个数组对象。

如果换做是一般对象呢?

很多程序设计语言(特别是 C++ 和 Pascal)提供了两种参数传递的方式:值调用和引用调用。

有些程序员(甚至本书的作者)认为 Java 程序设计语言对对象采用的是引用调用,实际上,这种理解是不对的。由于这种误解具有一定的普遍性,所以下面给出一个反例来详细地阐述一下这个问题。

class User {
    private String name;

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

    public String getName() {
        return name;
    }

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

    @Override
    public String toString() {
        return name;
    }
}


测试:

public class test{
        public static void main(String[] args) {
        User A = new User("ali");
        User B = new User("bd");
        System.out.println("交换前name:" + A + "-->" + B);
        swap(a,b);
        System.out.println("交换后name:" + A + "-->" + B);
    }

    private static void swap(User a, User b) {
        User tmp = a;
        a = b;
        b = tmp;
    }
}


运行结果为:

交换前name:ali-->bd
交换后name:ali-->bd


发现还是没有交换!

所以到底有没有交换,主要是看它修改的是变量(引用)还是修改的堆里面的对象。

交换前:


交换后:

 

 


通过上面两张图可以很清晰的看出: 方法并没有改变存储在变量 A 和 B 中的对象引用。swap() 方法的参数 a 和 b 被初始化为两个对象引用的拷贝,这个方法交换的是这两个拷贝。

那么到底该如何实现交换两个变量的值呢?

用容器(或者数组)
例如:

public class test{

    public static void main(String[] args) {
        int[] arr = {2, 3};
        int A = arr[0];
        int B = arr[1];
        swap(arr, 0, 1);
        A = arr[0];
        B = arr[1];
        System.out.println(A);
        System.out.println(B);
    }

    public static void swap(int[] arr, int a, int b){
        int tmp = arr[a];
        arr[a] = arr[b];
        arr[b] = tmp;
    }
}


运行结果为:

3
2


用反射


public static void swap(Integer a, Integer b) throws Exception {
    Field field = Integer.class.getDeclaredField("value");
    field.setAccessible(true);   //设置可以访问成员的私有不可变的变量
    Integer tmp =new Integer(a.intValue());
    field.set(a, b.intValue());
    field.set(b, tmp);
}


http://chatgpt.dhexx.cn/article/XIcYmJ2X.shtml

相关文章

Java的值传递和引用传递

Java的值传递和引用传递 值传递&#xff1a;对形参的修改不会影响到实参 。引用传递&#xff1a;对实参的修改能够影响到实参 **Java是值传递&#xff1a;如果是基本数据类型&#xff0c;就是复制一份值传递给形参&#xff1b;如果是引用类型&#xff0c;那就将引用复制一份&…

Java 值传递和引用传递

值传递:在调用函数的时候,将实际参数复制一份传递到函数中,这样在函数中对参数进行修改的时候,就不会影响到原来的实际参数 引用传递:在调用函数的时候,将实际参数的地址直接传递函数中,这样在函数中对参数进行修改的时候,就会影响到实际参数值传递 引用传递…

go 语言值传递和引用传递

值传递 普通的值传递 package main import "fmt" func main(){fmt.Println(Hello("hello"," fpp")); } func Hello(stringName string,stringName2 string)(string){return stringNamestringName2; }string类型是引用传递吗? package main i…

Java 的值传递和引用传递

一、概述 Java数据类型分为基本类型和引用类型。相应的&#xff0c;变量也有两种类型&#xff1a;基本类型和引用类型。 1️⃣基本类型的变量保存原始值&#xff0c;即它代表的值就是数值本身。包含&#xff1a; 整型&#xff1a;byte&#xff0c;short&#xff0c;int&#…

java值传递和引用传递(附实例)

java值传递和引用传递&#xff08;附实例&#xff09; 1.数据类型1.1 基本数据类型1.2 引用数据类型 2.形参与实参2.1 函数中使用2.2 调用 3.值传递和引用传递3.1 定义3.2 例子3.3 结论 观前提示&#xff1a; 本文所使用的IDEA版本为ultimate 2019.1&#xff0c;JDK版本为1.8.…

java中的值传递和引用传递

个人理解&#xff0c;可能会有错误之处&#xff0c;请仔细甄别&#xff0c;谨慎参考&#xff01;如有错误或不同见解请指出&#xff01; 值传递&#xff08;Pass By Value或者Call By Value&#xff09;是对基本型变量而言的,传递的是该变量的一个副本,改变副本不影响原变量。…

【JAVA】值传递与引用传递

一.声明 Java中没有引用传递 二.值传递和引用传递 值传递&#xff1a;就是在方法调用的时候&#xff0c;实参是将自己的一份拷贝赋给形参&#xff0c;在方法内&#xff0c;对该参数值的修改不影响原来的实参。 引用传递&#xff1a;是在方法调用的时候&#xff0c;实参将自…

值传递与引用传递详解

1、关于值传递 值传递&#xff1a;是指在调用函数时&#xff0c;将实际参数复制一份传递到函数中&#xff0c;这样在函数中如果对参数进行修改&#xff0c;就不会影响到实际参数 如下图所示&#xff0c;当传递参数之前会将参数进行复制&#xff0c;函数中修改了参数&#xff0c…

值传递与引用传递的区别

一、值传递&#xff1a;是指在调用函数时将实际参数复制一份传递到函数中&#xff0c;这样在函数中如果对参数进行修改&#xff0c;将不会影响到实际参数。 ​ 代码在内存中的执行流程&#xff1a; 1、首先加载main方法&#xff1b; ​ 2、接下来int number 100&#xff1…

什么是值传递,什么是引用传递?

1、什么是值传递&#xff0c;什么是引用传递&#xff1f; 值传递&#xff08;pass by value&#xff09;是指在调用函数时将实际参数复制一份传递到函数中&#xff0c;这样在函数中如果对参数进行修改&#xff0c;将不会影响到实际参数。引用传递&#xff08;pass by referenc…

Java复习总结之快速区分值传递和引用传递

引言 为了搞清楚值传递和引用传递的区别&#xff0c;查阅了许多资料&#xff0c;加以自身理解&#xff0c;做出本篇博客用于记录。 概念 值传递&#xff1a;指在调用函数时将实际参数复制一份传递到函数中&#xff0c;这样在函数中如果对参数进行修改&#xff0c;将不会影响到…

华为应聘进展状态码解析(附加性格测试攻略)

多方查找咨询终于终于看到了自己的状态码&#xff0c;总结一下~ 性格测试攻略&#xff1a; https://blog.csdn.net/guomutian911/article/details/48915301 https://blog.csdn.net/twc829/article/details/51226358 https://blog.csdn.net/twc829/article/details/51226247 第三…

华为OD机试2023 最新最全备考攻略助你轻松上岸

【华为OD机试真题 2022&2023】真题目录 点这里 【华为OD机试真题】信号发射和接收 &试读& 点这里 【华为OD机试真题】租车骑绿道 &试读& 点这里 什么是华为OD 华为OD是Outsourcing Dispacth模式&#xff0c;是华为和外企德科联合招聘的简称。目前华为大多…

idea 怎么导入maven项目

1、打开一个现有的IntelliJ IDEA工程&#xff0c;点击菜单的“File”->“new”->“Module from Existing Sources”。 更详细请点击&#xff1a;http://yayihouse.com/yayishuwu/chapter/1826

IntelliJ IDEA如何导入Gradle项目

https://blog.csdn.net/wangdong5678999/article/details/70255451 IntelliJ IDEA如何导入Gradle项目 栋先生 2017-04-20 10:14:03 95942 收藏 分类专栏&#xff1a; 其他 文章标签&#xff1a; idea intellij idea gradle 版权 最近学习Gradle&#xff0c;本文来重点介绍…

杂记——16.idea中导入maven项目

这篇文章我们来讲一下如何从Gitee上拉取项目&#xff0c;并将该项目导入到idea中 目录 1.拉取项目 2.idea导入项目 3.更改相关的配置 3.1更改maven仓库 3.2更改数据库的连接池 1.拉取项目 第一步&#xff1a;找到相关的项目地址 如图所示&#xff0c;在Gitee上找到相关的…

idea项目导入eclipse中步骤

1、打开eclipse&#xff0c;右键import 找到需要导入的项目 2、重新配置tomcat&#xff0c;已经配置好了建议移除后重新添加&#xff0c; window-preference 3、项目上右键-debug AS-发现没有 debug on server,这是没有转成web项目 项目右键-properties 配置好后会出…

idea与eclipse项目相互导入方式

目录 idea项目往eclipse中导入 idea项目导出到桌面 idea项目导入到工程中 idea项目迁徙到eclipse 第一种导入方式&#xff1a; 第二种导入方式&#xff1a; 第三种导入方式&#xff1a; eclipse项目往idea中导入 idea项目往eclipse中导入 idea项目导出到桌面 直…

idea中导入maven项目并运行

当我们从网上下载人家的maven项目该怎样导入并运行呢&#xff0c;请看如下步骤。 File->New->Project from Existing Source 选择maven项目下的pom.xml文件 File -> Project Structure 填写编译输出路径 6. 如果右边的某些项是红色的&#xff0c;点击右边的maven进行…

IDEA中导入Maven工程或项目

IDEA中导入Maven工程或项目 本文简单讲述了IDEA中导入Maven工程或项目。为了减轻读者压力笔者将 IDEA 相关应用技巧分解成了多篇文章置于主页 IDEA 专栏&#xff0c;若本文没有帮助到您&#xff0c;请去主页 IDEA 专栏检索吧 &#x1f60f;。 文章目录 IDEA中导入Maven工程或项…