问题1:在判断两个String 是否相等的时应该用equals()函数 以为==只能检测到两个String是否是同一地址(公用)所以String s1 = "aaaa";
  String s2 = "aaaa";是true; (“aaaa”放在一个地址里 s1和s2同指向一个地址)String s11 = new String("aaaa");
  String s22 = new String("aaaa");不是在同一地址里
  

解决方案 »

  1.   


    你没有理解 "aaa" 是什么!
    其实在Java中 "aaa" 就是String类的一个实例,它是有地址的。String s1;
    s1 = "aaa";
    只是将"aaa"的地址传给s1.
      

  2.   

    String s1 = "aaaa";
      String s2 = "aaaa";
      System.out.println("s1 == s2 is " + (s1==s2));
      显示结果为true;不肯能是true的,返回的是false。
      

  3.   

    to: apple21(编姑娘的小花篮) 感谢你的回答
        那么第2个问题如何解释呢?
    to: likeBean(喜欢吃咖啡豆)
        我是在Jbuildx里测试的,上面的所有代码我都测试了的
        你也可以测试以下
    to:XioSan(Milo)
        不太明白你的解释,可否详细一些?
      

  4.   

    纠正一下,是我搞错了
     apple21(编姑娘的小花篮)说的挺对的啊,a==b比较的是地址,
    String s1 = "aaaa";
      String s2 = "aaaa";
    jvm会分配一块地址给"aaaa",然后然s1和s2都指向这块地址,所以返回的是true;
    String s11 = new String("aaaa");
      String s22 = new String("aaaa");
    jvm会给s11和s22各分配一块地址,所以返回的是false;这是java语法的问题,所以没有为什么的答案,只有说java编译器就是这么干的,详细的
    你可以参考java tutorial,说的很清楚。
      

  5.   

    我也发表一下意见:)
    其实
    String s1 = "aaaa";
    String s2 = "aaaa";
    等价于
    String st = new String("aaaa");
    String s1 = st;
    String s2 = st;
    这样好理解XioSan的解释了吧!
      

  6.   

    apple21(编姑娘的小花篮) 的回答是正解
      

  7.   

    第二个问题,其实传递对象的时候也是传值的,只不过这个值是对象的一个引用而已,所以你参数为String s1时,传递了s1引用的一份拷贝。当你重新在子函数中使用s="bbb"的时候,只是把s1的引用的那份拷贝重新指向了新的地址,原来s1还是"aaa"字符串的一个引用并没有变化,明白否?
      

  8.   

    那对于StringBuffer类型来说如何解释呢?谢谢
      

  9.   

    dlxu(沿着Java继续前进) 是对的
    下面一例子
    public class Test {
        public static void test(String str) {
            str = "World";
        }
        public static void main(String[] args) {
            String string = "Hello";
            test(string);
            System.out.println(string);
        }
    }
    输出是:Hello
    但是其实String类型依然是传引用的,一切模糊来自String支持"="
    main函数中假设string是一个String对象的地址引用,假设值为0xccef
    调用test(string)时将string的值入栈,在test中它被指向另一个"World"串,这个引用
    指向另一地址,但是在返回时所有入栈参数会Pop,string的地址值会恢复
      

  10.   

    再来考就StringBuffer,比较一下StringBuffer和String的两个成员函数,JDK源码
    String:
               public String replace(char old,char new) {
                  .......
        while (++i < len) {
    if (val[off + i] == oldChar) {
        break;
    }
        }
        if (i < len) {
    char buf[] = new char[len];//注意这里,在成员方法的局部栈空间内,
                                                   构造一个String中char序列的副本,并无
                                                   修改自身的成员"private char[] val"
    for (int j = 0 ; j < i ; j++) {
        buf[j] = val[off+j];
    }
    while (i < len) {
        char c = val[off + i];
        buf[i] = (c == oldChar) ? newChar : c;
        i++;
    }
    return new String(0, len, buf);
                  }StringBuffer:
        public synchronized StringBuffer append(String str) {
    if (str == null) {
        str = String.valueOf(str);
    } int len = str.length();
    int newcount = count + len;
    if (newcount > value.length)
        expandCapacity(newcount);
    str.getChars(0, len, value, count);//注意这里,新加入的str被切实
                                                  加到StringBuffer自身的成员
                                                  "private char[] value"中
    count = newcount;
    return this;//这是为了支持诸如a.append().append()的链式调用
        }
     
    这就是为什么StringBuffer的修改函数能起修改传入对象的作用
      

  11.   

    你把setValue(String s)中的s = "bbb";屏蔽掉就知道是怎么回事了。
    他被来传进来的是引用,然后又被"bbb"覆盖了。
    自己去琢磨吧。
      

  12.   

    第二个给出的是利用字符串缓冲区的覆盖方法
    public StringBuffer replace(int start,int end,String str)来覆盖给定的地址内容。
      

  13.   

    JAVA不象VC和C,他为了提高程序的运行性能,对字符串的操作提供了String and StringBuffer两种方法。String类用于存储和维护值不变的字符串对象,而StringBuffer用于存储和维护值可以改变的字符串对象。
      

  14.   

    哦,我明白了,在使用String类型是,函数setValue中“=“的问题使得结果有所不同,明白了,谢谢各位
      

  15.   

    The following are examples of string literals: "" // the empty string
    "\"" // a string containing " alone
    "This is a string" // a string containing 16 characters
    "This is a " + // actually a string-valued constant expression,
    "two-line string" // formed from two string literals

    Because Unicode escapes are processed very early, it is not correct to write "\u000a" for a string literal containing a single linefeed (LF); the Unicode escape \u000a is transformed into an actual linefeed in translation step 1 (§3.3) and the linefeed becomes a LineTerminator in step 2 (§3.4), and so the string literal is not valid in step 3. Instead, one should write "\n" (§3.10.6). Similarly, it is not correct to write "\u000d" for a string literal containing a single carriage return (CR). Instead use "\r". Each string literal is a reference (§4.3) to an instance (§4.3.1, §12.5) of class String (§4.3.3). String objects have a constant value. String literals-or, more generally, strings that are the values of constant expressions (§15.28)-are "interned" so as to share unique instances, using the method String.intern.
    Thus, the test program consisting of the compilation unit (§7.3): package testPackage;
    class Test {
    public static void main(String[] args) {
    String hello = "Hello", lo = "lo";
    System.out.print((hello == "Hello") + " ");
    System.out.print((Other.hello == hello) + " ");
    System.out.print((other.Other.hello == hello) + " ");
    System.out.print((hello == ("Hel"+"lo")) + " ");
    System.out.print((hello == ("Hel"+lo)) + " ");
    System.out.println(hello == ("Hel"+lo).intern());
    }
    }
    class Other { static String hello = "Hello"; }and the compilation unit:package other;
    public class Other { static String hello = "Hello"; }produces the output:true true true true false trueThis example illustrates six points:1.Literal strings within the same class (§8) in the same package (§7) represent references to the same String object (§4.3.1). 
    2.Literal strings within different classes in the same package represent references to the same String object. 
    3.Literal strings within different classes in different packages likewise represent references to the same String object. 
    4.Strings computed by constant expressions (§15.28) are computed at compile time and then treated as if they were literals. 
    5.Strings computed at run time are newly created and therefore distinct. 
    6.The result of explicitly interning a computed string is the same string as any pre-existing literal string with the same contents.
      

  16.   

    也就是说,在调用setVal时,s1的地址保存在栈里,在setVal时,“=“并没有把原来的s1指的字符串内容覆盖掉,而是将s1指向了另一个字符串,但是这个字符串在方法结束时自动释放了,s1就恢复了以前的值,使这个意思吧
      

  17.   

    这样说有个问题了,如果我定义了一个String变量,那么我怎么才能改变它的内容呢?
      

  18.   

    抄自thinking in javaObjects of the String class are designed to be immutable……you'll see that every mothod in the class that appears to modify a String really creates and returns a brand new String object containing the modification.
      

  19.   

    String的内容改变只能重新生成新的String,想要经常变更它的内容就用StringBuffer
      

  20.   

    呵呵,我现在总结一下:
    在传递值时,参数值得内容不会因为在函数内变化了而变化;在传递引用的时候,如果该变量所值的内容发生了变化,则相应的内容会发生变化,如果只是把变量所指的地址发生了变化,那么函数返回时该变量所对应的地址还是以前的
    下面这个例子可以说明这个问题:
    public class Test
    {  public int i,  j, 
      public void test_m( Test a)
      {  test5 b = new Test();
         b.i = 1;
         b.j = 2;
         a = b;
      }
      public void test_m1( Test a )
      {  a.i = 1;
        a.j = 2;
      }
      public static void main(String argv[])
      {  Test t= new Test();
         t.i = 5;
         t.j = 6;
         System.out.println("t.i = "+ t.i + " t.j= " + t.j);
         t.test_m(t);
         System.out.println("t.i = "+ t.i + " t.j= " + t.j);
         t.test_m1(t);
         System.out.println("t.i = "+ t.i + " t.j= " + t.j);
      }
    }
    函数test_m是在函数内改变了该参数的地址,并没有改变该参数所指的内容,所以,函数返回时恢复以前所指向的地址,显示得还是以前的内容;
    函数test_m1是在函数内改变了该参数所对应的内容,所以函数返回时指向以前的地址,此时,该地址的内容已经发生变化了,显示得是改变后的内容。
      

  21.   

    String的值是不能改变的,StringBuffer的值才能被改变的,
    equset比较值,==是比较地址.
      

  22.   

    String和StringBuffer都是string的子类
      

  23.   

    强烈建议对String类型有不彻底明白的,多去了解JVM及相关更深层的内容,如:常量池等。这才是解决这个老生长谈的问题的根本。
      

  24.   

    faint看了半天一半说的对一半说的是错的根本在误人子弟
      

  25.   

    我也是刚学,你可以去买本thinking in java
      

  26.   

    有的回答根本就是错误的
    string a="aaaa" 
    这么定义的a根本不叫句柄,而叫做非句柄变量,指向的不是一个堆地址。但是他所在的地方都是栈,因为string是常用的主类型,所以为了简便调用要放到栈而不是堆里。java里的对象都是由new或者返回一个对象的方法来定义的,每用1个new就生成一个新对象
    String a=new String("aaaa")
    这个a才叫指向对象的句柄,比较句柄实际是比较2个句柄所指的堆内存,就算保存的内容一样,但地址肯定是不一样的。
      

  27.   

    楼上练内功的,其实"aaaa"这种也不是放在栈里的吧,由于string比较特殊,jvm会管理一个string pool,你可以注意一下string有一个intern的方法,这种string,jdk的帮助文档里明确说明是默认intern的,intern之后会被放进字符串pool里面,也不是在栈上分配的
      

  28.   

    学习中,Thinking in java 里面说得很清楚.
      

  29.   

    zhengkan(十大杰出神仙) 说得对
    java不会在栈内分配对象