前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >面试专题:值传递和引用传递的问题

面试专题:值传递和引用传递的问题

原创
作者头像
小明爱吃火锅
发布2023-12-26 14:57:34
1590
发布2023-12-26 14:57:34
举报
文章被收录于专栏:小明说Java小明说Java

前言

在Java编程中,参数传递有两种方式:值传递和引用传递。这两种传递方式决定了变量在方法内部的变化如何影响原始变量。本文将深入探讨这两种传递方式的概念、应用和注意事项,并且从面试题入手,分栈堆内存的情况。

一、值传递与引用传递

值传递是指在方法调用时将实际参数(原始变量)的副本传递给形式参数。这意味着在方法内部对形式参数的修改不会影响实际参数。值传递在传递基本数据类型(如int、float、double等)和引用数据类型的包装类(如Integer、Float、Double等)时发生。

引用传递是指在方法调用时将实际参数的引用(内存地址)传递给形式参数。这意味着在方法内部对形式参数的修改可能会影响实际参数。引用传递通常发生在对象类型上。

二、面试案例

看一下面试题,看起来就几行代码很简单,那么到时a和b最终结果是什么呢?

运行结果,输出的是AB B,而不是AB,AB

占堆内存分析:

一开始栈中有a和b变量,分别指向堆中的A和B。a->000x1(A),b->000x2 (B)

operator(a, b);操作,新增了方法局部变量x和y,并且也是指向A和B。x->000x1(A),y->000x2 (B)

接下来,x操作append,拼接y,x指向对应的内存值000x1(A)变成了000x1(AB);而y = x,表示的是y指向了x的内存地址。

最终y->x->000x1(AB)。此时,a和b的只想其实都没变化,a还是指向000x1,b还是指向000x2。所以a和b对应的值是

AB和B。

如图最终栈堆内存图:

如果改成这样,就可以看到四个变量最终的值了,跟我们上面分析的结果一样。

代码语言:java
复制
public class Test {
    public static void main(String[] args) {
        StringBuffer a = new StringBuffer("A");
        StringBuffer b = new StringBuffer("B");
        operator(a, b);
        System.out.println(a + " " + b);
    }

    public static void operator(StringBuffer x, StringBuffer y) {
        x.append(y);
        y = x;
        System.out.println("y:" + y + " ,x:"+x);
    }
}

最终结果

总结

这个问题其实涉及到了,变量的范围,x和y只有在operator生效,不会影响到a和b,但是如果operator接受的是对象,则传递的是地址而不是值,如果方法改变地址的内容(比如x.append(y)),外部引用的变量(比如a)获取到的值也会更新。所以方法的参数传递机制,如下规则: (1)形参(形参是在函数定义中声明的参数)是基本数据类型 传递数据值 (2)实参(实参是在函数调用时传递给函数的值)是引用数据类型 传递地址值 特殊的类型:String、数组 包装类等对象不可变性

我正在参与2023腾讯技术创作特训营第四期有奖征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、值传递与引用传递
  • 二、面试案例
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档