黑马程序员技术交流社区

标题: 请教一个有关于字符串对象的问题 [打印本页]

作者: 李然    时间: 2013-12-9 17:59
标题: 请教一个有关于字符串对象的问题
string s = "aas"中的s在内存中有一个对象:"aas"。它存在于内存中方法区的常量池中
而String x = new String("aas")中的x在内存中有两个对象: "aas"和new String("aas")。"aas"存在于内存中方法区的常量池中,new String("aas")存在于栈内存中。
--------------------------------------------------------------
各位大神,以上是我个人对字符转对象在内存中位置的一个理解,不知道对不对,如果不对的话,请各位大神指导一下小弟。这种问题,可能意义不大,但是作为基础个人感觉应该还是了解一下比较好。
作者: 熊猫86    时间: 2013-12-9 20:01
哈哈,是不是被我的问题也给搞晕了?话说new对象是在堆内存中不是在栈内存中,其它应该木有问题
作者: .ˋMr.Ivan    时间: 2013-12-9 20:03
答案是肯定对的。你看一下下面的例子
public class Test1 {

        /**
         * @param args
         */
        public static void main(String[] args) {
                String str1 = "abc";
               
                String str2 = new String("abc");
               
                String str3 = "abc";
               
                System.out.println(str1 == str3);
               
                System.out.println(str1 == str2);

        }
}
结果为:true
            false
这个例子呢,可以证明用常量赋值的方法确实是在方法区创建了一个字符串常量,同时也证明了 常量赋值和new对象的方式所创建的对象不是同一个。
但是还没有证明用new的形式是创建两个对象,但是我在一些树上看过对这个问题的说明,用new创建一个字符串对象确实是在栈内存和方法区创建了两个。
作者: 小痞痞    时间: 2013-12-9 20:09
所有new出来的东西都存在于堆内存中
作者: 乔_博_文    时间: 2013-12-9 20:23
我先分析一下,希望能帮到楼主~
     我们可以把String x = new String("aas")这行代码分成String str、=、"aas"和new String()四部分来看待。String str只是定义了一个名为str的String类型的变量,因此它并没有创建对象;=是对变量str进行初始化,将某个对象的引用(或者叫句柄)赋值给它,显然也没有创建对象;现在只剩下new String("aas")了。那么,new String("aas")之所以创建了两个对象,是因为调用了String的构造器:public String(String original){.....}.正是使用new调用了String类的构造器方法创建了一个对象,并将它的引用赋值给了str变量。同时,被调用的构造器方法接受的参数也是一个String对象,这个对象正是"aas"。
     再回头看看String a="aas";,这行代码被执行的时候,JAVA虚拟机首先在字符串池中查找是否已经存在了值为"aas"的这么一个对象,它的判断依据是String类equals(Object obj)方法的返回值。如果有,则不再创建新的对象,直接返回已存在对象的引用;如果没有,则先创建这个对象,然后把它加入到字符串池中,再将它的引用返回。
这是我的理解~
作者: 流星舞夜    时间: 2013-12-9 20:34
这两种方法产生的对象确实不是同一个对象。
String x = new String("abc");
通过new出来的对象是在堆中创建对象的,x作为引用指向在堆中创建的对象。
String x ="abc"是直接在静态常量池中创建的一个对象。
作者: 李然    时间: 2013-12-9 20:57
熊猫86 发表于 2013-12-9 20:01
哈哈,是不是被我的问题也给搞晕了?话说new对象是在堆内存中不是在栈内存中,其它应该木有问题 ...

。。。。。哈哈。。。
作者: 李然    时间: 2013-12-9 21:04
.ˋMr.Ivan 发表于 2013-12-9 20:03
答案是肯定对的。你看一下下面的例子
public class Test1 {

多谢大神!
作者: 李然    时间: 2013-12-9 21:25
小痞痞 发表于 2013-12-9 20:09
所有new出来的东西都存在于堆内存中

多谢。。。。。。。。。。。:lol
作者: 李然    时间: 2013-12-9 21:27
乔_博_文 发表于 2013-12-9 20:23
我先分析一下,希望能帮到楼主~
     我们可以把String x = new String("aas")这行代码分成String str、=、 ...

多谢高手!




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