黑马程序员技术交流社区

标题: 字符串对象创建 [打印本页]

作者: 愿㊡╃數曐曐メ    时间: 2013-5-29 23:15
标题: 字符串对象创建
public class test
{
public static void main(String [] args)
  {
   String s1="abc";
    String s2=s1;
    String s3="abc";
    }
}
请问一下能创建多少个字符对象呢?
作者: 逝者轨迹    时间: 2013-5-29 23:17
不太明白你说的什么意思,能说清楚点吗
作者: 神之梦    时间: 2013-5-29 23:20
n+1         
作者: 张林敏    时间: 2013-5-30 13:08
本帖最后由 张林敏 于 2013-5-30 13:12 编辑

其实这3个 s1 s2 s3 指向的是同一个字符串常量
作者: 吴刚—heima    时间: 2013-5-30 13:15
我也不懂你说的意思,你可以说清楚一点。
作者: 张超    时间: 2013-5-30 15:17
张林敏 发表于 2013-5-30 13:08
其实这3个 s1 s2 s3 指向的是同一个字符串常量

敏敏有卖萌了,说清楚点呀。
作者: 紫衣侯    时间: 2013-5-30 16:31
string 类只是引用类型而已,可以自己添几句 system.out.print(s1==s2);  system.out.print(s1==s3); 多试试就明白了
作者: 袁梦希    时间: 2013-5-30 17:03
我个人理解:

我看着好像就一个对象。因为"abc"是在常量池中,无论多少个变量指向他,他都是一个对象。
然后又让s2指向了"abc",根本就是多个变量在操作同一个对象。

欢迎反驳
作者: 逝者轨迹    时间: 2013-5-30 20:14
只针对这段代码的话,应该是一个对象,s1、s2、s3指向同一个对象"abc",s1,s2,s3是三个String类型的常量
作者: Changer_s    时间: 2013-5-30 21:22
看上去好像都是指向的同一个引用对吧?因为他们都没new对象,都只是引用“abc”的那个内存地址
那到底是不是呢?记住用eclipse实验哈子,因为软件运行结果不会骗人
public static void main(String[] args) {
                String s1="abc";
            String s2=s1;
            String s3="abc";
            System.out.println(s1==s2);
            System.out.println(s1==s3);
            }
        }
结果:
true
true
实际上最准确的比较方法还是比较字节码
        public static void main(String[] args) {
                String s1="abc";
            String s2=s1;
            String s3="abc";
            Class cl1 = s1.getClass();
            Class cl2 = s2.getClass();
            Class cl3 = s3.getClass();
           System.out.println(cl1==cl2);
            System.out.println(cl1==cl3);
            }
结果:
true
true

结果显示指向同一个地址,也就是他们都是指向的是同一个内存地址!

作者: Changer_s    时间: 2013-5-30 21:23
袁梦希 发表于 2013-5-30 17:03
我个人理解:

我看着好像就一个对象。因为"abc"是在常量池中,无论多少个变量指向他,他都是一个对象。

呵呵,团长
作者: 张甲甲    时间: 2013-5-30 22:11
执行过程应该是这样的:java虚拟机首先会看它的栈中是不是有“abc”这个字符串常量,如果有 内存中就有一个引用s1指向它,如果没有 java虚拟机就先生成一个“abc”放在它的栈里面,然后让s1指向它。然后s2是s1的一个引用。因为栈中的数据是可以共享的,所以s3也是指向栈中的这个“abc”。所以 s1 s2 s3其实都指向的栈中的统一字符串。
如果 s1=new String("abc");就是生成的一个对象了 ,这个对象会放在堆里面 。
这也是java堆好栈的区别
个人意见。。。。。
作者: Sofoul    时间: 2013-5-30 23:03
本帖最后由 Sofoul 于 2013-5-30 23:22 编辑

可以创建很多个,只要你愿意,不过没啥意义,字符串操作非常耗费内存。

无标题234234.png (25.84 KB, 下载次数: 0)

无标题234234.png

作者: 刘正祥    时间: 2013-5-30 23:28
可以创建很多,知道内存撑不下来的时候,你定义一个对象引用,就固定在的内存中开辟一个内存空间,对象类型都一样的话,那么每个的容量就确定了,用内存的总容量除以你定义的对象引用的容量,就可以算出来能定义多少个。
作者: 残影    时间: 2013-5-30 23:39
在内存中开辟了一个空间,存放“abc”,,s1=”abc“于是得到了他的地址,然后s1==s2,所以s2也得到了“abc”地址,然后s3=”abc“也是同一个abc,所以得到的也是abc的地址啊。。。是不是呢?
作者: Lobon    时间: 2013-5-31 00:02
1个!!!
作者: 郭天龚    时间: 2013-5-31 23:06
      你如果问的是你上面的代码创建了几个字符串对象,那肯定是创建了一个字符串对象"abc"。
String s1,String s2,String s3 只是定义了三个String类类型的引用变量,他们三个都引用"abc"这个字符串对象。
作者: xiewen    时间: 2013-6-1 23:19
肯定只创建了一个对象,就是只创建了一个“abc”对象,它存在于常量池中,s1,s2,s3这三个引用指向的是同一个“abc对象”。
作者: 苑永志    时间: 2013-6-15 00:21
本帖最后由 苑永志 于 2013-6-15 00:22 编辑
Changer_s 发表于 2013-5-30 21:22
看上去好像都是指向的同一个引用对吧?因为他们都没new对象,都只是引用“abc”的那个内存地址
那到底是不 ...

你的理解好像有点问题呀,你说
”实际上最准确的比较方法还是比较字节码“
所有String对象在内存中都只对应一个Class实例(class字节码),也就是任意一个String对象str.getClass()返回的结果都是相等的,跟字符串是否指向同一个对象是毫无关系的
作者: Changer_s    时间: 2013-6-15 13:56
苑永志 发表于 2013-6-15 00:21
你的理解好像有点问题呀,你说
”实际上最准确的比较方法还是比较字节码“
所有String对象在内存中都只对 ...

后面的确有点问题,现在还是对字节码产生了疑惑,为什么比较的时候要用:== 来比较。就像你的一样,那如果是同一种类型的比较,他们的字节码永远都一样,那张孝祥老师说的==比较是什么意思呢?
作者: 苑永志    时间: 2013-6-15 15:26
Changer_s 发表于 2013-6-15 13:56
后面的确有点问题,现在还是对字节码产生了疑惑,为什么比较的时候要用:== 来比较。就像你的一样,那如 ...

比较他们Class对象的引用地址的
得到某个Java类的Class实例的方式(以String为例):
1. Class c1 = String.class
2. Class c2 = 字符串对象.getClass();
3. Class c3 = Class.forName("java.lang.String");
c1,c2,c3的都是指向的是同一个Class对象的引用
作者: a767175432    时间: 2013-6-15 15:36
只创建有一个对象 对象是在堆内存中的 引用变量是创建在栈内存中的
刚开始 "abc"这是一个匿名对象会被放在一个叫常量池的地方,当“abc”赋给一个引用变量的时候 会首先找常量池有没有“abc”如果有就将“abc”所在常量池的地址返回
果断上图

作者: Spole_168    时间: 2013-6-15 21:05
在堆中他们指向同一个字符串对象地址,就像楼上所画的图一样。。。




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