• 为什么Java中你写的swap()函数无法实现两数交换?你真的深入了解Java中的栈和堆了吗?


    作为一个Java初学者,相信我们都会写过swap(int a,int b)函数,然后写完运行之后我们会发现,它其实无法完成我们对两个数交换的要求,这是为什么呢?要解决这个问题,我们需要了解到JVM中的栈区和堆区两个。


    🌈JVM的栈区和堆区:

    栈:栈区是一个数据结构,它的特点是先进后出,栈中存储的是方法的临时变量(局部变量和形参),它随着方法栈帧(方法在调用过程中申请的一块空间)一同存在和销毁,当方法调用结束,方法栈桢弹出,方法中所有的临时变量全部销毁。

    堆:在Java中所有使用关键字new产生的对象都储存在堆中,对于new出来的引用数据类型而言,保存它的是一块堆内存的地址。

    代码示例:

        public static void main(String[] args) {
            int[] arr=new int[]{10,20};
        }
    
    • 1
    • 2
    • 3

    对于上述代码的解释:
    1.该语句在堆上产生了一个数组对象,数组对象保存了两个数组元素10和20,在堆中存储。
    2.在栈上开辟了一个局部引用数据类型变量arr保存了堆中数组的首地址。

    若是理解不透彻,详细可以去看这篇带图讲解的博客,:Java中基本数据类型和引用数据类型存放的位置(栈内存和堆内存)


    🌈为什么swap()无法实现交换两个数呢?

    代码:

    package Java_1;
    
    public class test {
        public static void main(String[] args) {
            int x=10;
            int y=20;
            swap(x,y);
            System.out.println("在main方法中 : "+"x = "+x+",y = "+y);
        }
        private static void swap(int x, int y) {
            int tmp=x;
            x=y;
            y=tmp;
            System.out.println("在swap方法中 : "+"x = "+x+",y = "+y);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    首先是main方法先入栈,栈中存储main方法的形参args和临时变量x、y,然后main方法运行到swap()函数处卡住,等待swap()运行结束,于是产生一个swap()栈帧压入栈中,swap中存储形参x、y和临时变量tmp,交换结束之后形参完成交换,但是不影响main方法中的x、y值,之后swap()运行到函数末尾,所以swap()出栈,里面的x、y、tmp变量全部被销毁,所以main中的x、y无法完成交换,最后main方法也会运行到结尾而出栈被销毁。总的来说,完成交换的是swap()中的形参变量,而main方法中的x、y没有改变。

    图示:
    在这里插入图片描述


    🌈如何使用swap()实现交换两个数呢?

    代码(使用arr数组来实现两数交换):

    package Java_1;
    
    public class test {
        public static void main(String[] args) {
            int[] arr=new int[]{10,20};
            swap(arr);
            System.out.println("在main方法中 : "+"arr[0] = "+arr[0]+",arr[1] = "+arr[1]);
        }
        private static void swap(int[] Arr) {
            int tmp=Arr[0];
            Arr[0]=Arr[1];
            Arr[1]=tmp;
            System.out.println("在swap方法中 : "+"arr[0] = "+Arr[0]+",arr[1] = "+Arr[1]);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

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

    首先是main方法先入栈,栈中存储main方法的形参args和临时变量arr,其中arr存储的是数组首元素的地址,数组的元素存储在堆中,然后产生一个swap()栈帧压入栈中,swap中的形参Arr接收的是main方法中的arr变量,也就是数组元素的首地址,所以Arr和arr可以看作是共同控制堆中数组的一个变量(类似于两个遥控器,可以共同操控一个东西),swap()运行完成之后,虽然Arr会被销毁,但是arr仍然可以访问堆中已经被交换的元素,一个遥控器坏了另外一个仍然可以使用,所以它可以完成元素的交换。

    图示:
    在这里插入图片描述

  • 相关阅读:
    SpringBoot+LayUI+MybatisPlus 前后端分离 实现数据表格下拉框功能
    2、VRP基础
    C#练习题7和8
    day06_面向对象基础
    【图像变换】基于matlab实现HSI和RGB域图像转换附matlab代码
    DeepExtrema: A Deep Learning Approach for Forecasting Block Maximain Time Series Data
    Sanitizers 系列之 leak sanitizer 介绍
    比特集训营第一课
    JavaWeb:JavaWeb技术架构演进
    21-SpringBoot JUnit5单元测试-断言机制
  • 原文地址:https://blog.csdn.net/qq_53130059/article/details/126468118