如题,小弟是菜鸟,不是很明白,其中的内存情况是怎么回事!

解决方案 »

  1.   


    ab
    abc
    和引用s
    四个对象.
    String 类是不能被改写的.
    StringBuffer可以.
      

  2.   

    a 和 b 和c 各是一个对象
    相对于String s=new String("a")+new String("b")+new String("c");
    a和b相加后ab为一个对象,
    ab+c又是一个对象
    整个过程产生了5个对象
    s指向的就是第5个对象。
    其余4个没有被引用的对象会在内存紧缺的时候被垃圾回收。个人理解,如果不对楼下一定改正。
      

  3.   

    to 3楼
    b对象没有被new出来怎么和a相加呢你都说了String类是不能被改写的
      

  4.   

    String 不用new的,StringBuffer需要new的
    如:
    String a = "Hello";
    System.out.println(a);StringBuffer bf = new StringBuffer("Hello");
      

  5.   

    看编译器有没有做优化了
    优化后的结果:String s="abc";//声明一个String引用指向常量池中的"abc"
                   //单纯这一句话不会生成新的对象,执行1万次也不会产生新对象
    如果不优化://常量池中有"a","b","c"三个字符串
    String s="a"+"b"+"c";//产生1个临时对象"ab",及一个"abc"
    对于常量池的字符串,不能认为是运行的时候才生成的,而是在编译之后就确定下来的
    因此答案是0个或2个
      

  6.   

    我只是打个比方当然不用new了,为了说明问题,因为显示的new 更加直观创建了对象
    String对象即便不写new实际上和写new效果完全等同的,因为String类太常用了,所以做了简化
      

  7.   

    我的答案不对,
    to 7楼 你的好像也不对正确的应该是1个对象,编译器优化的结果
    http://java.ccidnet.com/art/3539/20070912/1210357_1.html我看了这篇文章同时有做了编译试验,跟踪了jdk源码。引用
    7楼 对于常量池的字符串,不能认为是运行的时候才生成的,而是在编译之后就确定下来的 
    "a"+"b"+"c"编译后和"abc"
    完全相同
    至少在程序运行时会产生一个对象,零个对象是不正确的
      

  8.   

    另外new String()创建的字符串不放入常量池中
    使用new和不使用new还是有区别的
      

  9.   

    String s="a"
    就在池中产生了一个,引用池中的,
    但String在做改变的时候实际上是将String转换为StringBuffer,而StringBuffer的操作实质上是使用char型变量,所以在下认为只有一个对象。
      

  10.   

    一共有3个对象,分别是:
    A
    AB
    ABC
    在引用池里也会有3个对应的对象。
    如果运行String 语句时,首先是在引用池里生成对应的对象A,AB,ABC;
    如果下次运行时有相同对象的时候引用池就直接调用这个对象,如果引用池里没有此对象的话就在堆区生成一个对象
    所以,首先在引用池里生成对象:A,AB,ABC;然后在堆区里生成相应的对象A,AB,ABC。
      

  11.   

    a   和   b   和c   各是一个对象 
    相对于String   s=new   String( "a ")+new   String( "b ")+new   String( "c "); 
    a和b相加后ab为一个对象, 
    ab+c又是一个对象 
    整个过程产生了5个对象 
    s指向的就是第5个对象。 
    其余4个没有被引用的对象会在内存紧缺的时候被垃圾回收。 =========================
    本来我也以为是这样的,看来不对啊
      

  12.   

    我觉的skyyun5个对象的说法比较正确
      

  13.   

    太复杂了,像redduke1202说得那样,是不是当问你的时候,还要分两种情况来分析
      

  14.   

    0个并没有创建对象;
    String s1="a"; //这种写法,"a"会被当作常量被保存起来
    String s2=new String("a"); //这种写法是创建一个String对象System.out.println(s1); //都是打出a;
    System.out.println(s2);String s="a"+"b"+"c";
    由是String是不可变长的,所以系统会创建一个更大的空间将a和b 存在这个空间里,之后再创建一个更大的空间把abc存起来,如果连加的太多就要用StringBuffer这个类了,写循环用这两个类分别加1000次效果就很明显了
      

  15.   

    对象只有1个,保持对字符串的引用!
    内存中会有 a ab abc 3个字符串
      

  16.   

    错了  内存中有5个字符串 a b c ab abc 
      

  17.   

    five in all, there are:
    "a";
    "b";
    "c";
    "ab";
    "abc".
    System.out.println(s=="abc");return true, which means they are the same object in the membery.
      

  18.   

    有没有方法可以监视对象new的状态啊
      

  19.   

    5个对象"a ";
    "b ";
    "c ";
    "ab ";
    "abc ".我不是专家,但是我这么认为,大家多支教
      

  20.   

    String s1 = "abcd";对应的虚拟机字节码:
       L0 (0)
        LINENUMBER 23 L0
        LDC "abcd"
        ASTORE 2======================================String s2 = "a" + "b" + "c" + "d";对应的虚拟机字节码:
       L1 (3)
        LINENUMBER 24 L1
        LDC "abcd"
        ASTORE 3
    没有区别。
      

  21.   

    如果pool共享池中已有"abc"标准字符串序列的对象,则产生0个对象
    如果pool共享池中没有"abc"标准字符串序列的对象,则在pool共享池产生一"abc"对象.引用变量s指向该对象。即产生1对象
      

  22.   

    能过上面的分析...我感觉应该是6个对象...
    "a",
    "b"
    "c"
    "ab"
    "abc"
    s----指向"abc"的引用也算一个对象
      

  23.   

    更正一下应该是五个..
    看看这个说明吧:
    哈哈,要理解这个,就要知道string类的工作原理。你知道在java中除了8中基本类型外,其他的都是类对象以及其引用。所以 "xyz "在java中它是一个String对象.对于string类对象来说他的对象值是不能修改的,也就是具有不变性。
    看:
    String   s= "Hello ";
    s= "Java ";
    String   s1= "Hello ";
    String   s2=new   String( "Hello ");啊,s所引用的string对象不是被修改了吗?之前所说的不变性,去那里了啊?你别着急,让我告诉你说发生了什么事情:
    在jvm的工作过程中,会创建一片的内存空间专门存入string对象。我们把这片内存空间叫做string池。String   s= "Hello ";当jvm看到 "Hello ",在string池创建string对象存储它,并将他的引用返回给s。
    s= "Java ",当jvm看到 "Java ",在string池创建新的string对象存储它,再把新建的string对象的引用返回给s。而原先的 "Hello "仍然在string池内。没有消失,他是不能被修改的。所以我们仅仅是改变了s的引用,而没有改变他所引用的对象,因为string对象的值是不能被修改的。String   s1= "Hello ";jvm首先在string池内里面看找不找到字符串 "Hello ",找到,返回他的引用给s1,否则,创建新的string对象,放到string池里。这里由于s= "Hello "了,对象已经被引用,所以依据规则s和s1都是引用同一个对象。所以   s==s1将返回true。(==,对于非基本类型,是比较两引用是否引用内存中的同一个对象)String   s2=String( "Hello ");jvm首先在string池内里面看找不找到字符串 "Hello ",找到,不做任何事情,否则,创建新的string对象,放到string池里面。由于遇到了new,还会在内存上(不是string池里面)创建 string对象存储 "Hello ",并将内存上的(不是string池内的)string对象返回给s2。所以s==s2将返回false,不是引用同一个对象。好现在我们看题目:
    String   s   =   new   String( "xyz ");
    首先在string池内找,找到?不创建string对象,否则创建,   这样就一个string对象
    遇到new运算符号了,在内存上创建string对象,并将其返回给s,又一个对象所以总共是2个对象
      

  24.   

    万事万物皆是对象
    我认为最后两个都是对象。s 引用变量abc 内存常量
      

  25.   

    我也认为是五个对象:
    "a","b","c","ab","abc"
    还请大家多多指教!
      

  26.   

    6个吧.
    "a","b","c","ab","abc",String声明的对象s
      

  27.   

    我也是个菜鸟  初学者
    java  语言的的字符串常量与其它语言没什么不同, 实际上对于用了双引号括起来的字符串常量  
    系统会默认的为它穿件一个无名的对象
    有三个引号 是3个
    string s=“a”是一个对象
    我不知道 string s=“a”+“b” 是两个 还是3个
    要是两个的话 上面的问题 就是3个  
    要是3个的话  答案 就是5个希望高手指点...........
      

  28.   

    这种编译器的简单优化行为肯定会做的,直接就是
    String s = "abc"编译,然后用工具反编译就知道,javap -c 也能看到
      

  29.   

    至少应该是5个:
    首先看这几行代码: String s ="a"+"b"+"c";
     String s_ = "abc";
     System.out.println(s==s_);结果为 “true”也就是说 s 和 s_ 指向了同一个对象。又因为代码中 s_ 明确的指明了其对象是 "abc" 。 所以此时应得出
    String s ="a"+"b"+"c"; 应该产生至少一个对象是"abc".其次就是关于"a" ,"b" ,"c". 本人认为,内存中创建了这三个对象。可以根据 47 层的朋友留言去理解。还有就是试想CUP和内存的关系,cup是从内存中获取数据,然后运算,最后得到数据.那么在内存中如果没有"a" ,"b" ,"c"那么哪来的"abc"?
    所以到这里本人认为至少已4个对象了.再有就是 s,它也是内存中开辟的一个空间,保存着对 实例 的引用.也更象一个容器.装载着某个实例(本人的愚见).它也应该算是一个对象.
    到这里至少是5个了.最后,在程序运行期间是否创建了 "ab" 或是说 "bc",本人无从考证.还请高人指明. 如有错误,请楼下指出.
     
      

  30.   

    sunyujia 
     
    等 级:
     发表于:2007-11-17 11:36:404楼 得分:0 
    a   和   b   和c   各是一个对象 
    相对于String   s=new   String( "a ")+new   String( "b ")+new   String( "c "); 
    a和b相加后ab为一个对象, 
    ab+c又是一个对象 
    整个过程产生了5个对象 
    s指向的就是第5个对象。 
    其余4个没有被引用的对象会在内存紧缺的时候被垃圾回收。 个人理解,如果不对楼下一定改正。 
     
    =================================================================================不知道你有没有看过Effictive Java,这书是写JDK的一牛人写的,现在跑去GOOGLE了,书中说,在写程序时,建议我们不能这样定义一个String:String   s=new   String( "a ")
    这样不会产生两个String,当时我也纳闷,原来是这样的:“a”本身已经是一个string了,再new了一次,就产生两个了。
    =================================================================================================

    对于LZ这个问题,我给你个权威的回答吧:其实编译成.class文件后string的加法是由stringbuilder/stringbuffer来连接的至于产生几个对象,当然是四个了。JDK不会傻到“a”+“b”也产生一个新对象,SUN那些大牛们难道会不知道PERFORMANCE吗。实际上,编译后可以会变成这个样子:StringBuffer ss = new StringBuffer();
    ss.append("a").append("b").append("c");
    String s = ss.toString;不信的话,可以去看下.CLASS文件反编译后看下。
    还是那句话,学东西要学精。我也在努力。
      

  31.   

    这样不会产生两个String,当时我也纳闷,原来是这样的:“a”本身已经是一个string了,再new了一次,就产生两个了。
    =====================================
    这里写错了,不好意思应改为:这样会产生两个String,当时我也纳闷,原来是这样的:“a”本身已经是一个string了,再new了一次,就产生两个了。
      

  32.   

    我觉得也是5 个,因为string定义后是不能被修改的,"a","b","c",各是一个,"a"+"b"(即"ab")是第四个,"ab"+"c"(即"abc")是第五个,s指向第五个
      

  33.   

    mayandbrisa 
    mayandbrisa 
    等 级:
     发表于:2007-11-20 16:10:1073楼 得分:0 
    至少应该是5个: 
    首先看这几行代码:   String   s   = "a "+ "b "+ "c "; 
      String   s_   =   "abc "; 
      System.out.println(s==s_); 结果为   “true”也就是说   s   和   s_   指向了同一个对象。又因为代码中   s_   明确的指明了其对象是   "abc "   。   所以此时应得出 
    String   s   = "a "+ "b "+ "c ";   应该产生至少一个对象是 "abc ". 其次就是关于 "a "   , "b "   , "c ".   本人认为,内存中创建了这三个对象。可以根据   47   层的朋友留言去理解。还有就是试想CUP和内存的关系,cup是从内存中获取数据,然后运算,最后得到数据.那么在内存中如果没有 "a "   , "b "   , "c "那么哪来的 "abc "? 
    所以到这里本人认为至少已4个对象了. 再有就是   s,它也是内存中开辟的一个空间,保存着对   实例   的引用.也更象一个容器.装载着某个实例(本人的愚见).它也应该算是一个对象. 
    到这里至少是5个了. 最后,在程序运行期间是否创建了   "ab "   或是说   "bc ",本人无从考证.还请高人指明.   如有错误,请楼下指出. 
       
     
    =========================================================================
    你的方法不对。
    输入结果之所以是true,是因为jvm做了优化,考虑到性能问题,Tiger(java se 5)把最近相同的的String存储到了同一个内存,因为毕竟它是不可变的。不信的话,你可以试试下面的代码。String s1 = "abc";
    String s2 = "abc";
    System.out.println(s1 == s2);
    结果是true,大家都知道 == 是用来比较内存地址的。这说明s1, s2是同一个内存地址。
      

  34.   

    绝对是四个。。
    产生几个不是你想出来的,你可以去看看编译后的.CLASS文件,反编译下。
    就会发现其中的奥秘了
      

  35.   

    4个吧,javascript高级程序设计中第84页有详细说明,只有a,b,c,abc,个人觉得道理是一样的
      

  36.   

    是5个。
    因为String的长度是不可变得。
    String s = "a" +"b" + "c";
    因为String 不是基本数据类型,所以要生成对象才能使用。
    先生成一个String对象"a",在生成一个String对象“b”,
    执行"a"+"b"的时候,要生成一个新对象“ab",s会指向这个对象,再生成对象"c",执行"ab"+"c",
    生成对象“abc",s指向这个对象,这就是这个表达是的执行过程。
    所以共生成了5个对象。"a","b","ab","c","abc"
      

  37.   

    to Graywolf8888 结合你的留言,看了一下 API 其中关于 String 有这样的描述:
    ================================================================================================
    Java 语言提供对字符串串联符号("+")和其他对象到字符串的转换的特殊支持。字符串串联是通过 StringBuilder(或 StringBuffer)类及其 append 方法实现的。字符串转换是通过 toString 方法实现的,该方法由 Object 类定义,并可被 Java 中所有类继承。有关字符串串联和转换的更多信息,请参阅 Gosling、Joy 和 Steele 合著的《The Java Language Specification》。
    ================================================================================================
    有所获。
    支持没有 "ab" 这个对象。
    其中你给我的留言中提到:
    ——————————————————————————————————————————————————————————
    String s1 = "abc";
    String s2 = "abc";
    System.out.println(s1 == s2);
    结果是true,大家都知道   ==   是用来比较内存地址的。这说明s1,   s2是同一个内存地址。
    ——————————————————————————————————————————————————————————
    本人认为正因为他们是同一个内存地址,更能证明其二者指向同一个对象。
    还有你提到的四个对象应该是 "a","b","c","abc" 吧 ?
    本人仍坚持 s 也为一个对象。曾经查阅过一些 c++ 的资料。其中有这样的解释。但也并非权威的资料。所以能否给出有力的论证。证明其不是一个对象。
      

  38.   

    应该是5个 看Thinking in java第四版第284页 
    上面有详细的说明 应该是先创建  a b c 然后再 ab abc
      

  39.   

    public class Test{
      public static void main(String[] args){
        String s="a"+"b"+"c";
      }
    }C:\java>javac Test.javaC:\java>javap -c Test
    Compiled from "Test.java"
    public class Test extends java.lang.Object{
    public Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   returnpublic static void main(java.lang.String[]);
      Code:
       0:   ldc     #2; //String abc
       2:   astore_1
       3:   return}
      

  40.   

    我靠了!还在数啊!,JAVA是从c++  发展来的 好好感受想c++就知道怎么回事了
      

  41.   

    这个问题,《Think in Java》帮不了你,我个不怎么喜欢《Think in Java》这本书的
    要了解编译器的基本行为
      

  42.   

    5个,分别是 a,b,c和abc连接的字符串和一个指向该串的引用
      

  43.   

    shz2008bj 是正确的,两个!!
    a b c 是一个,他们指向的s又是一个。
      

  44.   

    to mayandbrisa我认为,对象的引用不是对象。Reference is not a Object。
    这怎么能混淆呢。。===================================================================其中你给我的留言中提到: 
    —————————————————————————————————————————————————————————— 
    String   s1   =   "abc "; 
    String   s2   =   "abc "; 
    System.out.println(s1   ==   s2); 
    结果是true,大家都知道       ==       是用来比较内存地址的。这说明s1,       s2是同一个内存地址。 
    —————————————————————————————————————————————————————————— 
    本人认为正因为他们是同一个内存地址,更能证明其二者指向同一个对象。 
    还有你提到的四个对象应该是   "a ", "b ", "c ", "abc "   吧   ? 
    本人仍坚持   s   也为一个对象。曾经查阅过一些   c++   的资料。其中有这样的解释。但也并非权威的资料。所以能否给出有力的论证。证明其不是一个对象。 =========================================================================C++和JVM完全是两个东西,明白吗?String   s1   =   "abc "; 
    String   s2   =   "abc "; 
    System.out.println(s1   ==   s2); 
    之所以输出TURE,是因为JVM做了优化,STRING对象的内容是不变的,为了节省内存,把它们放到了一个内存地址里。
    实际上,在JAVA SE5之前,结果输出是FALSE。这个论题其实和这里讨论的没多大关系。实际上,JAVA文件在编译成字节码之后,都会做处理,所谓的内存分配问题是装入CLASS字节码后,JVM才真正开始分配内存。
    String s = "a" + "b" + "c";这样的语句会被处理成:String s = "abc"; 而如果写成:String s = new String("a") + new String("b") + new String("c");则会用StringBuilde/StringBuffer来处理了,所以,这个问题没必要再讨论了。与其在这里说这些无谓的话题,还不如去好好学学JAVA,把基础打牢。多关注下JAVA EE呢,设计方面的论题更值得研究。
     
     
      

  45.   

    Reference   is   not   a   Object。 ================》》》Reference   is   not   an   Object。