黑马程序员技术交流社区

标题: String对象问题 [打印本页]

作者: 青春随了风    时间: 2015-8-5 21:30
标题: String对象问题
总是感觉有点混,
String s1 = "abc";
String s2 = new String("abc");
他们在内存中的具体区别是怎样的,以及存储位置是怎样的?
作者: wode1311    时间: 2015-8-5 21:45
s1是直接指向方法区的常量池,而s2先在堆里开辟一个空间存放String对象,指向"abc"对象的地址,有两个String对象。其实这个没有太大的意义,只要大致了解就行了。
作者: zaydon369    时间: 2015-8-5 21:53
除了面试,谁会这样定义:String s2 = new String("abc");
尼玛,就是怕面试,不然怎么写都ok啊.
s1是直接指向方法区的常量池,
而s2先在堆里开辟一个空间存放String对象,指向"abc"对象的地址,有两个String对象。
作者: hellojavacode    时间: 2015-8-5 21:55
“abc”存在方法区,然后s1直接指向方法区的abc。new了之后s2会在堆内存中开辟空间,然后s2指向堆内存的位置,然后“abc”的地址会赋给堆内存中的对象,
作者: HOTSUMMER    时间: 2015-8-5 22:00
s1内的abc在方法区的常量池,只有一个字符串对象,s2是两个对象,一个String对象,在堆内,一个“abc”对象,在常量池
作者: 玉质彼端    时间: 2015-8-5 22:01
(1)String s1 = "abc";
    在程序编译期,编译程序先去字符串常量池检查,是否存在"abc",如果不存在,则在常量池中开辟一个内存空间存放"abc"。然后在栈中开辟一块空间,命名为"s1",存放值为常量池中"abc"的内存地址。
(2)String s2 = new String("abc");
    和上面步骤类似,也会在程序编译期,检查常量池,保证常量池中有且仅有一个存放"abc"字符串的内存空间。
    但是,与上面不同的是,计算机还会在堆(Heap)内存中开辟一个存放字符串"abc"的空间。
    最后在栈中开辟一块空间,命名为"s2",存放"abc"在堆内存中的引用。

因此,字符串比较中 s1 == s2 返回false,因为这是s1栈中的值与s2栈中的值比较。
但是s1.equals(s2)返回true,这是值比较,估计是s1指向的常量池值"abc"与s2指向的堆值"abc"的比较。

作者: Morrfree    时间: 2015-8-5 22:04
简单点来说    第一种创建方式  只在方法区的常量池中创建了一个字符串对象.
第二种new方式,在堆中常见了两个对象,.
作者: 大木木    时间: 2015-8-5 23:27
什么什么池?新手上路只知道栈和堆




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