黑马程序员技术交流社区

标题: string类的问题 [打印本页]

作者: 邱国    时间: 2012-6-17 14:29
标题: string类的问题
本帖最后由 邱国 于 2012-6-17 19:27 编辑

    我们知道,string类是一个很特殊的类,类一般都要实例化创建对象,我们用new来创建对象,但是如果是这样,
String s1 = “abcd”,String s2 = new string("abcd"),String s3 =  s1 + "abcd";.
我想问的是,上面的3条语句都是创建对象吗?还是只是用关键字new,才是真正的创建了对象?
  
作者: 龙秋地    时间: 2012-6-17 14:49
上面三条语句都是创建对象,但是不一样的是:
  1. String s1 = “abcd”
复制代码
这句语句说明s1是一个类类型变量,"abc"是一个对象.
字符串最大特点:一旦被初始化就不会改变.
  1. String s2 = new string("abcd")
复制代码
这句话中s2在内存中有两个对象,new是一个对象,而且"abcd"又是一个对象.
  1. String s3 =  s1 + "abcd"
复制代码
而这句话有一个对象,就是"abcd"+"abcd"=="abcdabcd";
所以不是只有new才能创建对象.以上三种都是.


作者: 梁清平    时间: 2012-6-17 14:49
String s = new String()
String s =””
上面两种情况实际上是相同的。分号里面代表的其实是一个对象。
两者相加当然也是产生一个对象。。
注意:字符串一但被初化它的值就不能再改变了。
所以当你对原有字符串进行相加的时候实际上是创建了一个新的字符串。。或者说改变了引用变量的指向。。

作者: 张_涛    时间: 2012-6-17 15:02
String对象有两种赋值方式,分为字面值赋值方式和new的方式,下面我分别介绍以下
首先理解一点:java运行环境有一个字符串池(string pool),由String类维护。此外,对象是分配在堆内存中的。
1.        String s = "aaa";(采用字面值方式赋值)
1)        查找String Pool中是否存在”aaa”这个对象,如果不存在,则在String Pool中穿件一个”aaa”对象,然后将String Pool中的这个”aaa”对象的地址返回来,赋给引用变量s,这样s就会指向String Pool中的这个”aaa”字符串对象
2)        如果存在,则不创建任何对象,直接将String Pool中的这个”aaa”对象地址返回来,赋给s引用
2.        String s = new String(“aaa”);
1)        首先在String Pool中查找有没有”aaa”这个字符串对象,如果有,则不在Sring Pool中再去创建”aaa”这个对象了,直接在堆(heap)中创建一个”aaa”字符串对象,然后将堆中的这个”aaa”对象的地址返回来,赋给s引用,导致s指向了堆中创建的这个”aaa”字符串对象
2)        如果没有,则首先在String Pool中创建一个”aaa”对象,然后再在堆(heap)中创建一个”aaa”对象,然后将堆中的这个”aaa”对象的地址返回来,赋给s引用,导致s指向了堆中所创建的这个”aaa”对象。

作者: 钟成军    时间: 2012-6-17 15:03
见图分析

未命名.jpg (20.67 KB, 下载次数: 15)

未命名.jpg

作者: 薄炳鑫    时间: 2012-6-17 15:05
都是在创建对象,但是这三个对象的地址值是不同的。
String s1 = “abcd”   打印出来是abcd
String s2 = new string("abcd")  打印出来是abcd
String s3 =  s1 + "abcd";  打印出来是abcdabcd
s1和s2的hashcode值是相同的,因为字符串的hashcode值是通过字符串的内容生成的。


作者: 晏文根    时间: 2012-6-17 15:30
1.String s1 = “abcd”,java先去缓冲池中寻找相同内容的字符串,有就直接用,没有就创建一个新的对象放在缓冲池里。
2.String s2 = new string("abcd"),就是在堆中创建一个对象,有s2指向

其实都是创建对象,只是存储方式不一样而已。一般情况下,建议使用后者,该方式采用字符串缓冲池机制,效率高。
作者: 李元峰    时间: 2012-6-17 16:35
钟成军 发表于 2012-6-17 15:03
见图分析

你画错了
常量字符串 不在堆内存,而在数据池,!
作者: 胡大强    时间: 2012-6-17 17:30
所谓对象,笼统的说,就是我们研究的事物。所以他们都创建了一个对象。
String类是finall型。当你String s1=“abcd”;初始化之后,s1的值不会再改变。
String s2=new String(“abcd”);实际创建了2个对象abcd;看下面的分析:
   所有的字符串都是String对象,由于字符串文字的大量使用,java字符串有一个文字池pool;实际上"abcd"本身就是文字池中的一个对象,在运行 new String()时,把文字池即pool中的字符串"abcd"复制到堆中,并把这个对象的应用交给s2,所以创建了两个String对象,一个在pool中,一个在堆中。
第三个和第一个差不多么~!
作者: 钟成军    时间: 2012-6-17 18:17
李元峰 发表于 2012-6-17 16:35
你画错了
常量字符串 不在堆内存,而在数据池,!

恩,知道了,谢谢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2