黑马程序员技术交流社区

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

作者: springing    时间: 2014-7-24 00:03
标题: String类的问题
String s1 = "123";
String s2 = new  String("123");

视频上说:  S1在内存中有1个对象,S2在内存中有两个对象。  之前觉得对啊,是这样。

今天又看了看,迷糊了,这句话的意思是不是:

S1,S2都是对这个字符串对象的引用  语句1产生对象“123”   语句2产生对象“123”和对象 new String(“123”)?

   我对我的理解突然迷糊了,到底是不是这个意思? 再听他说的那句话好像不是我理解的这个意思
作者: springing    时间: 2014-7-24 00:35
求助,勿沉
作者: 关度飞    时间: 2014-7-24 00:44
这样子的,内存里有一个字符串池。
1.当你写String str="abc";时,先在栈里面新建str,然后检查这个字符串池中有没有abc,如果没有,就新建字符串“abc”,然后把“abc”的引用传递给栈里的str;如果已经有“abc”,就直接把“abc”的引用传递给str,而不会再去新建一个。
2.当你写String str=new String("abc");时,先在栈里面新建str(对应String str),再在堆里面新建一个匿名字符串对象(对应new String()),然后检查字符串池中有没有“abc”,如果没有,新建一个“abc”,并把它复制到堆里面的匿名字符串对象,然后将匿名字符串的引用传递给str;如果字符串池中有“abc”,则直接把这个字符串复制到堆里面的匿名字符串对象,然后将匿名字符串的引用传递给str。(注意在堆中每次new一个String()都会分配新的内存,而不会判断内容是否相同)
所以当你这样写:
  1. String str1=“abc”;
  2. String str2="abc";
  3. String str3=new String("abc");
  4. String str4=new String("abc");
复制代码

str1、str2的引用都是字符串池中的同一个String对象的引用,而str3、str4是堆里的不同String对象的引用,且堆里的String对象的是从同一个字符串里的String对象复制过来的。所以这里只有str1==str2的结果是true,其他之间相等的判断均为false。(== 为判断二者的引用是否为同一个)
而str1.equals(str2)为判断其内容是否相同,因为String重写了equals方法,所以两两之间结果均为true。
作者: springing    时间: 2014-7-24 05:06
关度飞 发表于 2014-7-24 00:44
这样子的,内存里有一个字符串池。
1.当你写String str="abc";时,先在栈里面新建str,然后检查这个字符串 ...

如果这样的话,
String  a = "abc";
String  b = new String("abc");

实际上第二行也只是创建了一个对象,因为abc这个字符串已经存在了!

作者: 晓_猪    时间: 2014-7-26 11:12
package itHeiMaTestz;
/**
* 首先 存储类型有: 栈 堆 常量池
*         而,new出来的对象放在堆中 例如:new String()
*                 常量放在常量池                例如:String str = "abc";        中的"abc"是常量
*                 基本类型放在栈中                例如: String str ;中的str是基本类型
*/
public class CHANGLIANGCHI {

        public static void main(String[] args) {
                String str1= "abc";        //在常量池中
                String str2 = new String("abc");
                System.out.println(str1==str2.intern()); //str2.intern() 就把堆中的对象复制到常量池中 结果:true
                System.out.println(str1==str2);                         //结果:false
        }

}

作者: liuniansis    时间: 2014-7-26 12:07
第一句,生成一个字符串对象,存储在常量池当中,如果String str2="123",那么就会直接把常量池中的对象地址值赋给他
第二种,因为new关键字,只要一出现new肯定就会在堆内存中创建一个新的对象,所以String str2=new String("123"):s2在栈内存中,new String("123")在栈内存中,s2存储的值是对象在堆内存中的首地址,而对象的值是"123"
第一句使用的是常量池中的地址,第二句使用的是堆内存中的地址
java中会生成五块区域.堆,栈,方法区,本地方法区,寄存器,常量池位于方法区当中:lol
作者: 北极£莜蓝    时间: 2014-7-26 15:02
String  a = "abc";//只在方法区中的常量池中 创建了一个字符串对象
String  b = new String("abc");//在堆  和方法区中常量池中都有都 对象




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