码迷,mamicode.com
首页 > 其他好文 > 详细

这个坑,是时候填上了...

时间:2020-12-10 11:08:41      阅读:2      评论:0      收藏:0      [点我收藏+]

标签:是什么   hang   现象   int   通过   基本   turn   class   内存地址   

一、背景

这两天,在网上逛的时候,发现了如下的一道面试题,感觉还有蛮有意思的,要是不仔细看还真容易掉到坑里面。第一眼看起来比较绕,所以比较难理解。最终我跳出了这个坑,也想把这个跳坑的经历分享出来。题目如下 , 请问输出的是什么?为什么?

/**
 * @author hafiz.zhang
 * @description: 一个奇怪的现象
 * @date Created in 2018/7/2 22:44.
 */
public class Test {
    public static void main(String[] args) {
        String ermao = "a";
        String bb = addStr(ermao);
        System.out.println(ermao);
    }

    private static String addStr(String ermao) {
        ermao = ermao + "b";
        return ermao;
    }
}

二、结果及原因

毫无疑问,这道题的答案是:a , 你答对了么?在讲解原因之前,让我们想了解一点基础知识吧:

1. 值传递还是引用传递

我们都知道Java中在传递参数的时候,分为值传递和引用传递两种类型。当参数为基本类型(Java八大基本类型:int、short、float、double、long、boolean、byte、char)的时候,就是值传递,当参数为封装类型(非基本类型,如Integer、Long、Boolean等)的时候,就是引用传递了。

2. Java内存模型中的堆和栈

从Java的底层机制来说,基本类型的变量存放在栈里;封装类型中,对象放在堆里,对象的引用放在栈里。Java在方法传递参数时,是将变量复制一份,然后传入方法体去执行。

3. 答案是a的原因

因为String类型在传递过程中的步骤如下:

  1. 虚拟机在堆中开辟一块内存,并存值”a”。
  2. 虚拟机在栈中分配给ermao一个内存,内存中存的是1中的堆地址。
  3. 虚拟机复制一份ermao,我们就叫ermao’好了,ermao和ermao’在栈中的内存不同,但此时存的值都是1的堆地址。
  4. 将ermao’传入方法addStr中。
  5. 方法体在堆中开辟一块新内存,并存值”ab”。
  6. 方法体将ermao’的值改变,存入5中新的堆内存地址。
  7. 方法结束,方法外打印ermao,由于ermao存的是1中分配的堆地址,所有打印结果还是”a”。

还不清晰?没关系,那我们直接上个图会不会来得更直观:
技术图片

三、总结

通过本文我们就理解了Java在方法传参的整个过程。其实还是上面那句比较重要的话Java在方法传递参数时,是将变量复制一份,然后传入方法体去执行。来一波掌声给棒棒的自己,点滴积累,方成大事~

阿豪说
学到了?请我喝杯咖啡吧~

这个坑,是时候填上了...

标签:是什么   hang   现象   int   通过   基本   turn   class   内存地址   

原文地址:https://blog.51cto.com/15047484/2560235

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!