论坛首页 Java企业应用论坛

[讨论]对"不可改变的字符串" 和"不可变类String"的理解。

浏览 13897 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2005-04-19  
不可改变的字符串具有一个很大的优点:编译器可以把字符串设置为共享。
不可变类String有一个重要的优点-它们不会被共享引用。


是这样的,JAVA为了提高效率,所以对于String类型进行了特别的处理---为string类型提供了串池 
定义一个string类型的变量有两种方式: 
string  name=  "tom  "; 
string  name  =new  string(  "tom  ") 
使用第一种方式的时候,就使用了串池, 
使用第二中方式的时候,就是一种普通的声明对象的方式 
如果你使用了第一种方式,那么当你在声明一个内容也是  "tom  "的string时,它将使用串池里原来的那个内存,而不会重新分配内存,也就是说,string  saname=  "tom  ",将会指向同一块内存 

另外关于string类型是不可改变的问题: 
string类型是不可改变的,也就是说,当你想改变一个string对象的时候,比如name=  "madding  " 
那么虚拟机不会改变原来的对象,而是生成一个新的string对象,然后让name去指向它,如果原来的那个  "tom  "没有任何对象去引用它,虚拟机的垃圾回收机制将接收它。 
据说这样可以提高效率!!!哈哈

------------------------
大家对此有什么理解?
   发表时间:2005-04-19  
第一句是强调String类所指的对象本身不可改变的特性,即使引用设为public也无妨,因为private就是为了防止被更改(当然也为了加密),而String类本身的特点就保证了这一点, 
第2句如下:String  stra=  "hello  world  "; 
                     String  strb=stra;/*该句并不会使strb与stra指向同一个对象,而是为strb创建了一个 
=  "hello  world“的副本,因此stra与strb指向不同的两个内存地址,只是两者的内容相同,以我的的推测,原文中第一处应为public,第二处应为share
0 请登录后投票
   发表时间:2005-04-20  
其它朋友是如何解释的。
0 请登录后投票
   发表时间:2005-04-20  
hidalgo 写道
第一句是强调String类所指的对象本身不可改变的特性,即使引用设为public也无妨,因为private就是为了防止被更改(当然也为了加密),而String类本身的特点就保证了这一点, 
第2句如下:String  stra=  "hello  world  "; 
                     String  strb=stra;/*该句并不会使strb与stra指向同一个对象,而是为strb创建了一个 
=  "hello  world“的副本,因此stra与strb指向不同的两个内存地址,只是两者的内容相同,以我的的推测,原文中第一处应为public,第二处应为share

感觉你的逻辑还不是很清晰,String类型的变量和String对象的值没有区分清楚
strb=stra这句恰恰会使strb指向stra所指向的String对象,并不会创建所谓的副本,因为这里是简单的变量赋值,stra的值是指向"hello world"String对象的引用。
至于你说的将引用设置为public也无妨,没有看明白你的意思
0 请登录后投票
   发表时间:2005-04-20  
是这样的,JAVA为了提高效率,所以对于String类型进行了特别的处理---为string类型提供了串池
定义一个string类型的变量有两种方式:
string name= "tom ";
string name =new string( "tom ")
使用第一种方式的时候,就使用了串池,
使用第二中方式的时候,就是一种普通的声明对象的方式
如果你使用了第一种方式,那么当你在声明一个内容也是 "tom "的string时,它将使用串池里原来的那个内存,而不会重新分配内存,也就是说,string saname= "tom ",将会指向同一块内存

另外关于string类型是不可改变的问题:
string类型是不可改变的,也就是说,当你想改变一个string对象的时候,比如name= "madding "
那么虚拟机不会改变原来的对象,而是生成一个新的string对象,然后让name去指向它,如果原来的那个 "tom "没有任何对象去引用它,虚拟机的垃圾回收机制将接收它。
0 请登录后投票
   发表时间:2005-04-21  
其实不仅仅时Java这么做了,连C编译器都是这么做的

char* str1 = “Hello“; 
char* str2 = “Hello“; 
*str1 = ‘P‘; 
cout << str2 << endl; 


你猜打印的结果是什么?
0 请登录后投票
   发表时间:2005-04-22  
在说String不可改变的时候举name="madding"的时候说生成一个新的对象并不确切,因为没有用new,所以"madding"也是串池中存在的对象而已。
垃圾回收理解没问题,任何没有引用指向的对象,在虚拟机看来都是垃圾
0 请登录后投票
   发表时间:2005-04-23  
rootsoso 写道
其实不仅仅时Java这么做了,连C编译器都是这么做的

char* str1 = “Hello“; 
char* str2 = “Hello“; 
*str1 = ‘P‘; 
cout << str2 << endl; 


你猜打印的结果是什么?


在vc6 和 dev c++4.9.8默认情况下是违规访问内存
str1指向的是一块常量地址.对它赋值是不允许的

不过这个和编译器有关.

btw,这是c++代码,不是c的
0 请登录后投票
   发表时间:2005-04-25  
String a="aa";
  String a1="aa"; 
  System.out.println(a.equals(a1)+" "+a.hashCode()+" "+a1.hashCode());
  String b=new String("aa");
  String b1=new String("aa");
  System.out.println(a.equals(b)+" "+a.hashCode()+" "+b.hashCode());
  System.out.println(b.equals(b1)+" "+b.hashCode()+" "+b1.hashCode());

输出:

true 3104 3104
true 3104 3104
true 3104 3104
0 请登录后投票
   发表时间:2005-04-25  
珂儿 写道
String a="aa";
  String a1="aa"; 
  System.out.println(a.equals(a1)+" "+a.hashCode()+" "+a1.hashCode());
  String b=new String("aa");
  String b1=new String("aa");
  System.out.println(a.equals(b)+" "+a.hashCode()+" "+b.hashCode());
  System.out.println(b.equals(b1)+" "+b.hashCode()+" "+b1.hashCode());

输出:

true 3104 3104
true 3104 3104
true 3104 3104


拜托啦小姐,String类的equals方法和hashCode方法都覆盖过的好不好。你这代码能说明什么呢?说明"aa"和"aa"确实是同样的字符串?
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics