我只知道一个是“b”,一个是引用它的a
为什么有人说这是3个对象呢?

解决方案 »

  1.   

    我怎么觉得只有一个呢??
    为什么是2个呢?
    new一个b放在对象池里。a只是对b的引用
      

  2.   

    2个 可以用这个验证:System.out.println("b" == "b");
    System.out.println("b" == new String("b"));
      

  3.   

    String s = "b";
    String sg = new String("bb");
      

  4.   

    new 出来的是一个对象,
    String a 这个变量是指向当前对象的一个引用吧。
      

  5.   

    String   s   =   "b"; 这样才是两个
    String   sg   =   new   String("bb");这样是一个
      

  6.   

    mysticpsvm 
    mystic 
    等 级:
     发表于:2007-12-14 17:15:1916楼 得分:0 
    String s="b";这样才是两个 
    String sg=new String("bb");这样是一个 
    --------------------------------------
    无语...
      

  7.   

    没错,就是3个。
    不信你看源代码
        public String(String original) { //构造函数
    int size = original.count;
    char[] originalValue = original.value;  //第一个字符串生成...
    char[] v;  //声明第二个字符串
       if (originalValue.length > size) {
          // The array representing the String is bigger than the new
          // String itself.  Perhaps this constructor is being called
          // in order to trim the baggage, so make a copy of the array.
        v = new char[size];//第二个字符串生成
          System.arraycopy(originalValue, original.offset, v, 0, size);
      } else {
          // The array representing the String is the same
          // size as the String, so no point in making a copy.
        v = originalValue; //第二个字符串生成  }
    this.offset = 0;
    this.count = size;
    this.value = v; //第三个字符串 .注意这里的value是String类里面的变量。
        }
    如果不相信你可以去看看相关java考试证书的书籍,上面写的很清晰。
      

  8.   

    2个
    一个字符对象,string a
    一个字符对象的引用对象,new string("b");
      

  9.   

    哈哈,要理解这个,就要知道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个对象 
      

  10.   

    应该是两个,heap中有一个也就是new出来的,在datasegment的中还有一个“b”
      

  11.   

    mysticpsvm   
    mystic   
    等   级: 
      发表于:2007-12-14   17:15:1916楼   得分:0   
    String   s="b";这样才是两个   
    String   sg=new   String("bb");这样是一个   
    -------------------------------------- 
    无语...
    ------------------------------------------
    人才!!!
    如果能看中间代码的情况就能看到分配几个空间了。
    我认为应该是1个~~
      

  12.   

    同意二十四楼
    “*”要先检察池内是否存在对象
    NEW 不管怎样都会创建新的对象
    所以两个
      

  13.   

    一个是在stack 里的对象引用,一个是在heap里的对象
      

  14.   

    一共产生了2个对象,但不包括你说的a,一个是在String pool中的生成一个(如果在其中没有的话),如果在堆中在复制一个,然后把这个的引用赋给a!
      

  15.   

    是三个也可以理解为两个,原因是"a"是一个字符串可以去看JAVA的语法,new String("a")是新开辟了一个空间放的是"a"这个字符串,第三个就是 String s = new String("a"),s指向new String("a"),感觉这个问题没有什么新意,做程序员第一个重要的是做出东西来,然后才是效能,当你能作出东西之后这些东西慢慢的会自己明白。
      

  16.   

    一个.
    String a 的意思是定义一个引用,= new String("b")的意思是动态产生一个String对象并返回给引用a.
      

  17.   

    太搞笑了, 共享池里创建了一个对象, 不直接引用, 还跑去再创建一个, 浪费内存啊,你们以为jvm的作者是傻蛋啊。
      

  18.   

    编译时刻 vs. 运行时刻,
    许多人都没有搞清楚!
    要想想如果做一个JVM,怎么才正确?
      

  19.   

    那要是按照24楼说的有String s="xyz";的前提下进行String s1=new String("xyz");只需要创建一个对象就可以了,因为共享池里的被人创建了
      

  20.   

    String a = new String("b");//两个String对象,常量池中一个,内存中一个;一个String类型引用,栈中
    String a = "b";//一个String对象,常量池中;一个String类型引用,栈中
      

  21.   

    搞清楚这个问题,先要弄懂java里面堆和栈的概念
    在java里面存在堆里面的东西才称为对象,基本数据类型(如:int,char)都存放在栈里面的。
    String   s="xyz";
    引用s 和“xyz”都是存放在栈中的东西,不是对象
    new   String("xyz");这个才是产生对象的
    所以就1个对象
      

  22.   

    String a = new String("b");
    a 是一个reference, 相当于c++中的指针, new String("b"); 是创建一个String, 用"b"来初始化, "b"在java中也可以认为是一个String对象,可以执行诸如"b".length()的操作.有几个对角没考虑过
      

  23.   

    是2个对象没有错的,放心吧,24楼那么权威,真让我心服,我之前也只是死记的,哈哈,
    因为这是一个java面试时常用的问题,
      

  24.   

     正如ls--achinese 提到的那样..我不知道JVM的作者会怎么弄..
    "
    太搞笑了,   共享池里创建了一个对象,   不直接引用,   还跑去再创建一个,   浪费内存啊,你们以为jvm的作者是傻蛋啊。
    "对于C++语言来说..显然就一个...我一看题目就觉得是1个对象,1个引用..我对JAVA理解不多,所以不好说什么...但如果答案真的是2个..
    我会比较鄙视jvm的作者的..
    设计的时候: 一个"bb"和new string("bb")  按着一般的道理应该是同一位置的..
    因为string又不能改变,你TMD的在内存里弄那么bb,, 这bb1 ,那bb2的觉得用户的内存很多吗???但如果string是能改变的话.."bb"和new string("bb")是需要不一样的..因为我们会改变后者,这时就不能在常量区操作了,的确需要给bb弄块内存出来...所以要是我来设计jvm(只是设计 ^_^), string a=new String("b"), 我就会把"bb" 和a引用 放一个位置上,都是常量区..
    当然判断方法24楼也已经说了..你创建个一个string("aa"),看它和常量区的"aa"比下是不是一个位置,c++当然好说.我不知道java能不能比..本人最后观点: 应该是一个..如果是两个..痛骂JVM的作者.妈的真是个傻蛋.哈哈 我又找到一条java垃圾的证据了.老妈一直催着吃饭...所以很可能理解出现大错误...  如果那样的话.嘻嘻 本人也是菜鸟...
    另外骂   "JVM作者什么傻蛋"  只是玩笑.突然想到new怎样处理应该是编译器作者的事情...哦..看来不关jvm作者的事情..不管怎样 我已经晕了 ..吃饭去也..
      

  25.   

    个人比较支持31楼的说话,一个是对象引用,存在栈stack或者datesegment中。一个是对象,在堆heap中. 我个人认为是一个。
      

  26.   

    piaopiao11 
     
    等 级:
     发表于:2007-12-17 10:56:0954楼 得分:0 
    搞清楚这个问题,先要弄懂java里面堆和栈的概念 
    在java里面存在堆里面的东西才称为对象,基本数据类型(如:int,char)都存放在栈里面的。 
    String       s="xyz"; 
    引用s   和“xyz”都是存放在栈中的东西,不是对象 
    new       String("xyz");这个才是产生对象的 
    所以就1个对象 
     
    =============“xyz”不在栈中,而是在String的常量池内,是内存中一块特殊的区域,所以“xyz”也是对象,共2个
      

  27.   

    2个,跟引用无关.
    new String("b");这样也是两个啊.
    "b"创建一个,new出来一个.
      

  28.   

    太经典了! 面试题目就是BT   看的懂24楼说的。很有意思。学JAVA就是在探讨这个东西,很好玩       明天拿去问问老师,看哪个才是正解。没看24楼的,觉得是一个,看重引用。看了,觉得是2个的依据十分充足。顶一个
      

  29.   

    三个对象:“b”、a、&a(a的引用)
      

  30.   

    a没自己的地址,不算
    "b"明显是一个
    new出来的也是一个
      

  31.   

    关于 那些说 
    ""b"明显是一个 
    new出来的也是一个"对于new,确实 平常的意思就要new出来一个..但是在这里由于string不能被改变..大家注定是一样的..
    就不应该再new一个...否则就是浪费内存了...  所以代码要求new的时候.."编译器"并不真正的new,而是检查发现已经有
    "bb"了 就直接指向常量区...反正用户也不能改变string,就不会出错的.所以说问题就看java "编译器"怎么对待new这个操作符了...  如果"new"真的一直一味不变当作new处理,我会鄙视JAVA的.
    呵呵...C++里的new是十分聪明的...24楼的回答,我也看了..我看见2个的答案的时候 就知道解释肯定会这样说的...我心里只是觉得多分配个内存出来很不爽..
    所以觉得应该只有一个...           我60 楼的..
      

  32.   

    同意73楼的说法
    怎么能是两个啊
    在新建String类型时,编译器会首先看看在对象池里有没有和要new的对象一样的名字,如果有编译器就不会
    再新建一 个了。直接指向那个对象。如果没有就会新建一个。所以就是一个对象啊! 
      

  33.   

    我同意24楼说的String b="bbb"和String b=new String("bbb");两者各有优缺点,String b="bbb"优点不用说了,省内存处理速度快,但是缺点就是频繁改变的话会创建很多对象,b=“111”,b="222",b="333",那么111,222还都存在,就是没有引用指向他了,因此String b="bbb"这种写法适合定义final类的数据;String b=new String("bbb");正如大家说的创建两个对象,但是好处就是频繁变化的话始终是两个变量,不会再增多了,适合于真正意义的变量的定义。所以JVM最聪明的地方在于提供多种机制,让你根据自己的需要选用不同的方式处理问题,JAVA里面没有指针,但是却需要指针才能完成的操作,JVM巧妙地运用了共享池对象创建的机制实现了和指针同样的功能并且操作起来更加方便。
      

  34.   

    73楼
    Java里new关键字一定是会分配内存空间,产生新的对象,这不能说Java没有C++“聪明”,不同编程语言在设计理念上会有不同,Java语言的语法还是以简洁为主要设计目标(虽然现在越来越复杂),new关键字会在不同的情况下保证有相同的语义;而且因为Java语言提供的垃圾回收机制,就像C#的托管机制一样,一般来说内存的使用效率不是首要考虑的因素,可能你习惯了C++,所以才会觉得多分配个内存出来很不爽..
      

  35.   

    String a = new String("b");
    a是一个引用,指向一个在heap区中被新创建的对象
    b是一个String类型常量,应该在常量池里面,在类的字节码被加载的时候创建的
    所以,我猜应该是2个对象
      

  36.   

    同意80楼说法,比较容易理解!
    支持2个对象String   a   =   new   String("b"); 
    可以拆分成如下2步操作
    String b = "b"; // 创建一个字符串对象 b
    String a = new String(b); // 此时,会再次创建一个对象a;帖一段测试代码和运行结果
    public class TestString {
      public static void main(String[] args) {    String a = "b";
        String b = new String(a);
        String c = "b";
        System.out.println("a==b?"+(a==b));
        System.out.println("a==c?"+(a==c));
      }
    }
    // 运行结果如下
    a==b?false
    a==c?true
      

  37.   

    i'm sure 
    it's two
      

  38.   

    “b”是一个对象,在String池中,然后又new了一个,所以是2个,书上都是这么说的,有什么好争论的呢
      

  39.   

    呵呵!大家不觉得楼主这个问题有点奇异的感觉!我们不能只拿这一句String a=new String("b")出来就说他一定是几个对象,这个不好说吧.一个程序中,他可能有会产生2个,也可能会产生一个。所以很多人说一个,没有错,说两个的也没有错,但是说三个的我就吧知道他什么怎么想的了。要看是在什么前提下,去判断他产生几个对象。
    如:1.  String a="b";       // 产生一个
            String a=new String("b");//这时,他就产生一个。因为String池中的已经有了,他就不用产生了。          2.   String a=new String("b"); //这是他就产生了两个,因为String中还没有,所以他就必须先在池中产生一
                                                  个,然后再NEW一个出来。
              String a="b";  //这时他就没有产生对象了。
      

  40.   

    回60楼的大哥:同C/C++不同,Java中存在String和StringBuffer的区别,前后两者对应不同的情况来使用.
    其中后者更接近于C++中的String.
    从某种意义上说,String其实是字符串常量而StringBuffer才是真正的字符串变量,这么理解的话JVM对这两者的处理机制就合情合理了.
    它就字符串的处理给出了两种方式供使用者选择.另外,我个人认为C++和JAVA不存在谁垃圾的说法,它们面向不同的场合.
    实际情况中,也许C++合适,也许JAVA合适.
    硬要说JAVA垃圾是没有任何道理的.
    以前还看见有人说C++垃圾,不如汇编纯粹,又不如SmallTalk抽象,我认为同样是无稽之谈.
    程序员应该更关注某种语言的优点而非缺点.
      

  41.   

    另外回21楼,别在类里边数,你把String类的一个属性和实际对象数加一起数出来了,真要这么算,那size也可以数进去变4个对象了....
      

  42.   

    可以说成一个或两个~出问题的人应该知道String的用法吧`在new a 的时候他抛弃了原有的对象~开创了一个空间,现在这个空间的值为null当它="b"的时候,就是另一个对象了`所以说可以说成一个或两个对象.
      

  43.   

    string a=new string("b");
    上面的语句如果a本身不算对象的话
    就可以肯定有2个对象
    看下面的描述从上面的语句看最后结果 string类型的a  引用了一个 string (这里是一个)
    这个被引用的string 来自 new string(xxx) (他是被a引用的所以这里不是新的)
    new string(XXX)中的初始化值XXX 你能说他不是对象吗?(所以这里又是一个)
    这样不是2个 是几个?可以说string a="b"; 和 string a=new string("b"); 明显的一样效果
      

  44.   

    吐血
    94楼:“new string(XXX)中的初始化值XXX 你能说他不是对象吗?(所以这里又是一个) ”
           XXX只是一个字面字面上的值而已,按你的说法我给小孩取名XXX,那么XXX也是个人了,就有两个小孩了同意86楼,栈中一个引用,堆中一个对象 
      

  45.   

    有空去研究一下JVM的内存结构就知道了PS:还可以去研究一下JDK里面String类的源代码,并注意一下intern()方法解释里面的用词public String intern()返回字符串对象的规范化表示形式。 一个初始时为空的字符串池,它由类 String 私有地维护。 
    当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。 
    它遵循对于任何两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。 
    所有字面值字符串和字符串赋值常量表达式都是内部的。字符串字面值在《Java Language Specification》的 §3.10.5 中已定义。 
    When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. 返回:
    一个字符串,内容与此字符串相同,但它保证来自字符串池中。
      

  46.   

    方法说明一切。如果只有1个对象,==号是成立的。
    String strA = "hello";
    String strB = new String("hello");
    strA == strB显然会返回false
      

  47.   

    98楼:“方法说明一切。如果只有1个对象,==号是成立的。”
    那么
    int i = 1;
    int ii = 1;System.out.println(ii == i);//返回true
    可现在一个对象也没有另外
    String s = null;
    String ss = null;
    System.out.println(ss == s);//返回true
    现在有几个对象?再另外
    String s = "a";
    String ss = "a";
    System.out.println(ss == s);//返回true
    现在又有几个对象?