当前位置: 首页 > article >正文

Java中的按值传递和引用传递

文章目录

  • 一、按值传递(Pass by Value)
    • 1.1 对于基本数据类型(如 `int`, `double`, `boolean` 等)
        • 示例:基本数据类型按值传递
    • 1.2 对于引用数据类型(如对象)
        • 示例:引用数据类型按值传递
  • 二、按引用传递(Pass by Reference)
  • 三、示例
  • 四、总结

在 Java 中,按值传递和按引用传递是两种常见的参数传递方式。为了深入理解这两种传递方式,我们需要从 Java 如何处理方法参数传递来入手。其实,Java 中所有的参数传递都是 按值传递,但是需要注意的是,对于对象参数,Java 按值传递的是引用的副本。

一、按值传递(Pass by Value)

在 Java 中,所有方法参数的传递方式实际上是 按值传递。这意味着当我们将一个变量传递给方法时,方法接收的是该变量的副本(值),而不是变量本身。

1.1 对于基本数据类型(如 int, double, boolean 等)

  • 传递的值是基本数据类型的副本。
  • 修改方法内部副本的值不会影响原始变量。
示例:基本数据类型按值传递
public class ValuePassing {
    public static void main(String[] args) {
        int a = 5;
        System.out.println("Before method call: a = " + a);  // 输出: a = 5
        modifyValue(a);
        System.out.println("After method call: a = " + a);   // 输出: a = 5
    }

    public static void modifyValue(int num) {
        num = 10;  // 修改的是 num 的副本,不会影响原始 a
    }
}

当我们将 a 传递给 modifyValue 方法时,方法接收的是 a 的副本。修改 num(副本)不会影响原始变量 a,所以 a 的值保持不变。

1.2 对于引用数据类型(如对象)

  • 对于对象类型,传递的是对象引用的副本。换句话说,传递的是指向对象内存地址的引用副本,而不是对象本身。
  • 修改对象的内容(通过引用副本)会影响原始对象,但如果改变引用的指向,则不会影响原始引用。
示例:引用数据类型按值传递
public class ReferencePassing {
    public static void main(String[] args) {
        Person p = new Person("John", 30);
        System.out.println("Before method call: " + p.getName());  // 输出: John
        modifyName(p);
        System.out.println("After method call: " + p.getName());   // 输出: Mike
    }

    public static void modifyName(Person person) {
        person.setName("Mike");  // 修改对象的属性,影响原始对象
    }
}

class Person {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

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

二、按引用传递(Pass by Reference)

  • 按引用传递是指方法接受的是对象的引用本身,因此方法可以直接修改原始对象的值。值得注意的是,Java 并不支持按引用传递
  • 在 Java 中,对于对象类型,实际上还是 按值传递,传递的是对象引用的副本,而不是引用本身。因此,我们不能在方法内改变引用的指向(例如指向另一个对象),但可以改变引用指向对象的内容。

三、示例

public class Main {
    public static void main(String[] args) {
        int a = 3;
        int b = 4;
        String zhang = "zhangsan";
        String li = "lisi";
        
        Peoplek i = new Peoplek();
        i.name = "i";  
        Peoplek j = new Peoplek();
        j.name = "j"; 
        
        test1(a, b);  
        System.out.println(a + " " + b); 

        test1(zhang, li);  
        System.out.println(zhang + " " + li);  
        
        test1(i, j);  
        System.out.println(i.name + " " + j.name); 
    }

    // 重载的 test1 方法,处理基本类型的传递(按值传递)
    private static void test1(int a, int b) {
        int c = a;
        a = b;
        b = c;
    }

    // 重载的 test1 方法,处理字符串的传递(按值传递)
    private static void test1(String zhang, String li) {
        String a = zhang;
        zhang = li;
        li = a;
    }

    // 重载的 test1 方法,处理 Peoplek 对象的传递(传递引用)
    private static void test1(Peoplek i, Peoplek j) {
        String a = i.getName();
        i.name = j.getName();
        j.name = a;
    }

    static class Peoplek {
        String name;
        
        public String getName() {
            return name;
        }
    }
}

  • ab 的值在 test1(a, b) 中没有改变,因为是按值传递。

  • zhangli 的值在 test1(zhang, li) 中没有改变,因为是按值传递(字符串是不可变的)。

  • i.namej.name 的值被互换,因为是传递的对象引用,修改的是对象的内容。

输出:

在这里插入图片描述

四、总结

  • 按值传递:方法接收到的是传入参数的副本,无论是基本类型的副本还是引用类型的副本。对于基本类型,副本的修改不会影响原始值;对于引用类型,副本的修改会影响原始对象的状态,但无法改变原始引用指向的对象。
  • 按引用传递(实际上 Java 不支持): 方法接收的是传入对象的引用本身,可以直接修改原始对象的内容,但不能改变引用本身。
    在这里插入图片描述

http://www.kler.cn/a/536167.html

相关文章:

  • DeepSeek本地部署保姆级教程
  • Word List 2
  • 【OS】AUTOSAR架构下的Interrupt详解(上篇)
  • 【玩转 Postman 接口测试与开发2_014】第11章:测试现成的 API 接口(下)——自动化接口测试脚本实战演练 + 测试集合共享
  • Python aiortc API
  • hot100(8)
  • 【AcWing】蓝桥杯辅导课-二分与前缀和
  • 虚基类和虚继承
  • 安卓7以上抓包证书安装
  • 2021 年 12 月青少年软编等考 C 语言五级真题解析
  • 《Kettle实操案例一(全量/增量更新与邮件发送)》
  • 深度学习-105-RAG技术之嵌入模型安装部署应用的三种方式
  • 初窥强大,AI识别技术实现图像转文字(OCR技术)
  • Mac下使用Docker安装CREMEB-PRO宝塔环境
  • 【Leetcode 每日一题】59. 螺旋矩阵 II
  • 广度优先搜索(BFS)算法详解——以走迷宫问题为例
  • 【JS】element-ui table展示勾选状态
  • AI工具——Cherry Studio,搭建满血DeepSeek R1的AI对话客户端
  • 【医院绩效管理专题】2.绩效管理:医院发展的核心驱动力
  • Jmeter接口自动化测试
  • ZIP完美解密解压缩和暴力破解最佳实现
  • python图片转字符画应用
  • Java 集合中的 `removeIf` 和 Stream API 的 `filter`
  • 4.Python字符串和列表:字符串输入、字符串输出、下标和切片、字符串常见函数、列表(list)、列表的循环遍历、列表的增删改查、列表的嵌套、列表的切片
  • 基于单片机的电子抢答器设计(论文+源码+实物)
  • Vue 3 30天精进之旅:Day 17 - 样式和动画