Java String、StringBuffer参数传递

来源:互联网 发布:知乎日报封面 编辑:程序博客网 时间:2024/05/27 00:28

java数据类型与参数传递  

2011-06-05 17:02:39|  分类:Java |  标签:|字号 订阅

在Java中,引用类型的变量非常类似于C/C++的指针。
基本类型与引用类型:
基本类型
java中int,float等属于基本类型,创建时存储于栈中。

引用类型

引用类型的引用存储于栈中,而对象则是存储与堆中。下面进行详细的阐述:

假设我们在函数中写了如下这个简单的语句:

StringBuffer str = new StringBuffer("Hello world"); 

别看这个语句简单,其实包含了如下三个步骤:

首先,new StringBuffer("Hello world")在堆里申请了一块内存,把要创建的StringBuffer对象放进去。

其次,StringBuffer str声明了一个指针。这个指针本身是存储在栈上的(因为语句写在函数中),可以用来指向某个StringBuffer类型的对象。或者换一种说法,这个指针可以用来保存某个StringBuffer对象的地址。

最后,当中这个等于号(赋值符号)把两者关联起来,也就是把刚申请的那一块内存的地址保存为栈中的str变量的值。

◆引用对象之间的赋值、判相等

通过上述的图解,大伙儿应该明白指针变量和该指针变量指向的对象是一个什么关系了吧。

还是接着刚才的例子,再来看赋值的问题。对于如下语句:

StringBuffer str2 = str;

这个赋值语句是啥意思?实际上就是把str的地址复制给str2,记住,是地址的复制,StringBuffer对象本身并没有复制。所以两个指针指向的是同一块堆区域。

再搞一张示意图,如下:

明白了赋值,判断相等的问题(就是==操作符)也就简单了。当我们写如下语句“if(str2 == str)”时,只是判断两个指针的值(也就是对象的地址)是否相等,并不是判断被指向的对象是否内容相同。

实际上两个指针的值相同,则肯定是指向同一个对象(所以对象内容必定相同)。但是两个内容相同的对象,它们的地址可能不一样(比如克隆出来的多个对象之间,地址就不同)。

参数传递:

这里我将会详细的介绍java中参数调用的时候,参数是如何传递的。这对于解决很多bt的面试题和平时的编程会有很大的帮助。

参数传递机制
call-by-value 值调用:将实际参数的内容拷贝到被调用方法

call-by-reference 引用调用:将实际参数的地址作为形式参数的值被传递到被调用方法。

(注意:一定要深刻理解上面的两种参数传递机制的真正含义。)
在java中,对于不管是基本类型还是引用类型,采用的都是值调用
存在一个方法method(RefParameter1,RefParameter2)。
此时,调用此方法,method(parameter1,parameter2);
执行的具体操作是:对实参parameter1,parameter2,采用值调用,即将实际参数的内容(对基本类型,会将其值copy;对于引用类型,其值不是堆中的某个对象,而是对象的地址,那才是实参的内容)拷贝到被调用方法的栈中。然后方法method根据传过来的参数进行方法的执行。

举例如下:
public static void change(String a){
        a = "changed" ;
    }
        public static void changeSB(StringBuffer a){
        a.append( "changed" );
    }

public static void changeSB2(StringBuffer a){
StringBuffer b= new  StringBuffer(“b”);       
a=b;
a.append( "changed" );
    }
   
    public static void changeInt(int a){
        int b=100;
        a=b;
    }

        int a=10;
        Test.changeInt(a);
        System.out.println(a);      //输出10
(这个应该容易理解。把a的内容,即10copy到方法中,无论如何改变都跟a无关。)
        String aa="111";
        String bb=new String("111");
        Test.change(bb);
        System.out.println(bb);      //输出为111
( 不管是采用aa创建的方式还是bb结果都一样。把对bb在堆中的对象的引用复制到change方法中,因为string为不可变量,a = "changed" ;会创建一个新的变量。对bb对象没有任何影响。)
        StringBuffer cc= new StringBuffer("111") ;
        Test.changeSB(cc);
        System.out.println(cc);     //输出为111changed
(这个是一个类对象的典型的例子。方法调用时会把参数cc的内容(StringBuffer("111") 对象的地址)复制到changeSB方法中,这时候方法中形参便也指向了对象StringBuffer("111") ,因此对他的修改会影响cc。)
StringBuffer dd= new StringBuffer("111") ;
        Test.changeSB2(dd);
        System.out.println(dd);     //输出为111
(这个理由很简单。方法changeSB2中,对引用a进行了重定向,指向了b。因此不会影响dd引用指向的内容)