zoukankan      html  css  js  c++  java
  • 一道印象深刻的面试题:String参数传递问题

             今天小菜去北京某知名公司面试,做了公司的面试题,然后就是轻松的面试。

             面试过程中,面试官让我讲讲其中一个题是怎么选的答案,代码大致内容如下:

     1 public class StringTest{
     2     public static void main(String[] args){
     3         String str = "s";
     4         
     5         changeStr(str);
     6         
     7         System.out.println(str);
     8         
     9     }
    10     
    11     private static void changeStr(String old){
    12         old = old + "-change";
    13     }
    14     
    15 }

             真实的输出结果应该是s,而小菜则错误的认为是s-change,还跟面试官讲了一堆道理。

             事后瞬间感觉学艺不精,羞愧难当。。。。

             这个结果为什么s呢?经过查阅资料,原来是String虽然以对象的形式存在,但仍认为是基本数据类型,就像Integer、Double那样,虽然是基本类型的包装类,但仍然认为是基本数据类型。

             既然认为是基本数据类型,因此无论在方法中如何操作,都不会影响到外界。

             其实,换个角度,也可以发现这样是错误的。

             首先,大家都知道字符串是不可改变的,简单理解即可,不做深入讨论。

             当我们把字符串当成参数传入方法时,传递的是值,是一个指针,这个指针指向了堆区的真实字符串,因此在方法中可以读到这个字符串,但是仅仅是能读到而已,当我们试图做如下操作时:

             str = str.replace(“a”,”b”);

             后边的str中保存的是原来的指针,的确是可以读到原来的字符串,然后执行替换操作,但是替换操作执行时,绝对不可能去修改原来的字符串,因为字符串是不可变的,因此只能是在堆区产生一个新的字符串,然后把新字符串的地址(指针)赋给str。

             此时str中保存的已经不再是原来的指针,因此读出的内容发生了变化,但不代表原来指针指向的内容发生了变化。

             另外,小菜顺便再补充一个知识点。

             关于Integer i = 1;和Integer i = new Integer(1);的区别。

             Integer i = 1;会直接从常量池中找到1,然后把地址赋给i,这样充分利用常量池,节省内存,注意除了字符串,其他类型的常量池都是有范围的,超范围了失效。

             Integer i = new Integer(1);这样写,写多少次,就在内存中创建多少个对象,每个对象里都保存了一个数字1,因此这样是极其浪费内存的,不推荐使用。

             常量池是保存在堆中的。

             小菜水平有限,不当之处多多包涵!

  • 相关阅读:
    Shiro配置文件ini详解
    Shiro配置文件ini详解
    [转]shiro基础教程
    [转]shiro基础教程
    arguments.callee的作用
    [转] C# WPF Unable to add event handler
    [转] C# WPF Unable to add event handler
    springmvcajax json对象 用Map接受
    springmvcajax json对象 用Map接受
    json 对象字符串相互转化, js中
  • 原文地址:https://www.cnblogs.com/iyangyuan/p/3199484.html
Copyright © 2011-2022 走看看