小毅小议Java字符串

Posted on 2008-08-25 12:22 H2O 阅读(229) 评论(0)  编辑  收藏 所属分类: java
首先我们来看以个小例子:
public class Test {
    
public static void changeStr(String str) 
{
        str 
= "welcome"
;
    }


    
public static void main(String[] args) {
        String str 
= "1234"
;
        changeStr(str);
        System.out.println(str);
    }

}
输出结果是什么?wecome?你错了,是 1234  为什么呢?原因如下:

<!--
    对象:一个对象可以被很多引用关联 
引用:一个引用只能关联一个对象

Ojbect xiaoyi1; Ojbect xiaoyi1; Ojbect xiaoyi1; 这里创建了三个引用 并没有创建对象

xiaoyi xy = new xiaoyi();

xy是一个引用, new xiaoyi()这个在内存中创建了一个对象,这个对象被 xy这个引用所关联
引用就好比一个句柄对象,通过xy这个引用(句柄对象) 可以操作 new xiaoyi()对象
引用也是一个值,只不过他的值记录了其关联对象的地址信息而已。
public void test(String s1){ 
只要是参数在方法内使用时,都会产生参数的副本的,记住这一点,无论java,C#,C,C++。 
1>String temp = s1;
这里s1只是一个引用的副本,是实际S1引用的一副本,好比你main方法内str实际引用的副本
2>s1="welcome";
在这里进行交换的时候你交换的仅仅是副本而已,虽然S1和main方法的str指向同一个对象,但是你交换的是main方法str引用的副本而已

另外:String str="XIAOYI";
str.toLowerCase() ;
System.out.println(str);
结果是什么?xiaoyi? 那么你又错了。。
因为在你调用toLowerCase()方法是会新开辟内存来保存转换完成的对象,而你并没有把原来对象的引用重新关联被转换后的对象,所以输出的仍然是转换前的对象 XIAOYI,要想改变结果怎么办?
重新关联:str=str.toLowerCase();  这样就可以了
-->

关于  Java字符串池(String pool)

public   class   Sub{  
String   str=new   String( "good ");   //一个地址的传递,new出来的对象,在内存中已经开辟了空间
 
public   static   void   main(String   args[]){  
Sub   ex=new   Sub();  
ex.change(ex.str);  
System.out.println(ex.str);  
}  
public   void   change(String   bb){  
bb= "test   ok " }

问题:String   str=new   String( "good ") 和String str="good"的区别?

体会1:str是一个String类型的对象引用,他是Sub类的类变量。当ex对象引用使用change方法时。bb是str引用的拷贝。可以通过bb访问原str的对象。而方法里当bb="test ok"的时候他把bb指向了一个新的对象中。这时候我们就要引出java字符串的概念了。

体会2:字符串池(转)String a = "Hello";
String b = "Hello";
String c = new String("Hello");
String d = new String("Hello");
System.out.println(a == b);
System.out.println(b == c);
System.out.println(c == d);
System.out.println(a.equals(b));
System.out.println(b.equals(c));
System.out.println(c.equals(d));

结果是true,false,false,true,true,true。这里就涉及到字符串池。“字符串池”,是Java为了提高内存利用率而采用的措施:

当遇到String a = "Hello"; 这样的语句时,Java会先在字符串池中寻找是否已经存在"Hello"这个字符串,如果没有,则建立字符串"Hello"对象,然后变量 a 指向这个地址;然后遇到语句String b = "Hello",这时字符串池中已经有 "Hello"了,所以直接让变量b也指向这个地址,省去了重新分配的麻烦。而在Java中,操作符“==”对于两个基本型来说,是判断其内容是否相同,对于两个对象来说,则是判断其地址是否相同,所以a == b返回 true。

那么String c = new String("Hello")又如何处理呢?如果是这种写法,则不会去访问字符串池,而是先为变量 c 开辟空间,然后将值写入空间。所以a == c返回false,c == d同样返回false。

至于String的equals方法,因为它比较的不是对象的地址,而是对象的值,所以都返回true就不奇怪了。

Java虚拟机有一个字符串池,保存着几乎所有的字符串对象。字符串表达式总是指向字符串池中的一个对象。使用new操作创建的字符串对象不指向字符串池中的对象但是可以使用intern方法使其指向字符串池中的对象.(注:如果池中已经有相同的字符串--使用equals方法确定,则直接返回池中的字符串,否则先将字符串添加到池中,再返回)。池中两个相等的字符串如果使用“==”来比较将返回真。

总结:也就是在change这个方法中,bb已经写入str空间。而bb在等于“test ok”的时候是运用字符串池创建了对象中了。所以不能赋值。可以这样 bb="test ok"; this.str=bb;

理解有错误,希望看到的高手可以告诉我,以便我可以更好的修改,谢谢了。



只有注册用户登录后才能发表评论。


网站导航:
 

posts - 0, comments - 21, trackbacks - 0, articles - 101

Copyright © H2O