String参数传递

来源:互联网 发布:中国石油数据 编辑:程序博客网 时间:2024/06/05 07:34
 public class StringTest{
    public static void main(String[] args){
           String str = "as";
  changeStr(str);
  System.out.println(str);
  }
   private static void changeStr(String str){

s="new String";

  }
 }
这个结果为什么是s呢?

String类型的变量作为参数时怎么会像基本类型变量那样以传值方式传递呢?

经过查阅资料,

值传递:方法调用时,实际参数把它的值传递给对应的形式参数,方法中执行形式参数值的改变不影响实际参数的值。

引用传递:也称为传地址。方法调用时,实际参数的引用(即地址,而不是参数的值)被传递给方法中相对应的形式参数,

在方法 中执行对形式参数的操作实际上就是对实际参数的操作(地址操作),这样方法执行中形式参数值的改变将会影响实际参数的值。

而String虽然以引用的形式存在,但在java语言中,以String作为类型的变量在作为方法参数时所表现出的是"非对象"的特性,所以仍认为是基本数据类型,而不是对象引用类型,就像Integer、Double那样,虽然是基本类型的包装类,但仍然认为是基本数据类型。 既然认为是基本数据类型,因此无论在方法中如何操作,都不会影响到外界

       再者可以这样理解: 首先,大家都知道字符串是不可改变的,当我们把字符串当成参数传入方法时,传递的是值,是一个指针,这个指针指向了堆区的真实字符串,因此在方法中可以读到这个字符串,但是仅仅是能读到而已,当我们试图做如下操作时:

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

因为String是final,所有在方法里改变变量的值,只是在常量池里重新创建一个而已!

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

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

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

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

 常量池是保存在堆中的。




0 0