这有几个和String有关的问题,请大家帮忙分析
1.
public class Test
{
    public static void main(String args[])
    {
           String s="abc";
           s=s.contact("def");
           System.out.println(s);
     } 
}执行结果为abcdef 书上不是说String的实例对象一旦创建,则它所包含的字符序列不发生变化吗?现在怎么变化了
2
public class J_String
{
    public static void operate(String x,String y)
   {
       x.contact(y);
      y=x;    }
   public static void main(String args[])
  {
     String a="a";
     String b="b";
    operate(a,b);
    System.out.println(a+"."+b);
   }}
执行结果为a.b,为什么operate中的y=x没有作用呢,x.contact(y),也没作用呢?
3.
public class J_StringArray
{
    public static void swap(String s[])
   {
     if(s.length<2)
        return;
     String t=s[0];
     s[0]=s[1];
     s[1]=t;
    }
    public static void main(String args[])
    {
    String s[]={"1","2"};
    swap(s);
    System.out.println(s[0]+s[1]);
    }
}
执行结果为21,为什么它们没有交换呢?
请大家针对这几个问题,给我讲讲这里面的门道,小弟在这谢谢大家了。

解决方案 »

  1.   

    1,contact是将"abc"连接def产生新的对象复制个x,原来的abc还是在的,并没有改变
      

  2.   

    1.String的实例对象一旦创建不可改变指的是String对象的内容不可改变,变量s只是一个引用,同一类型的引用只要不是final的,指哪儿都行,经过s.contact("def")之后又重新生成一个字符串,s原来指向“abc”,后来指向abcdef了
    2.java是值传递,而且String是final的,不可变的
    3.是交换了,字符串数组可以理解为对一个特殊的对象,里面的属性字段都是字符串,属性改变了,那整个对象肯定变了,就像下面public class StringObject
    {
    String str; public static void main(String[] args)
    {
    StringObject so = new StringObject();
    so.str = "abc";
    System.out.println(so.str);
    so.str = "def";
    System.out.println(so.str);
    so.union("ghi");
    System.out.println(so.str);
    }

    public void union(String s)
    {
    str +=s;
    }
    }
      

  3.   

    1、String是final类型的,s="adc"创建后就丢在池里,你后面contact后就是新的对象,然后交给引用s.2、x.contact(y)已经作用了,它创建了一个字符串对象,放在在String池里,只是你没有引用它;
    y=x;此处也是起作用的,你在这句下面加个打印就知道了。
    但回到main方法中:
    String a="a"; //一个对象
    String b="b"; //一个对象
    按理说是一个引用的交换,但这里没有将a="b",到是与值类型相似了,这里我还真没有研究过,待高人指点。3、结果不是已经交换了么?开始是 1,2,后面是2,1。难道我看错题了?
      

  4.   

    第一个问题看一下方法的源码就知道了public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
    return this;//传入0长度的字符串返回自身
        }
        char buf[] = new char[count + otherLen];
        getChars(0, count, buf, 0);
        str.getChars(0, otherLen, buf, count);
        return new String(0, count + otherLen, buf);//返回新的字符串了
    }
    楼主要搞清楚引用(句柄)跟对象的区别,借用编程思想的比喻:引用相当于“遥控器”,对象相当于“电视机”,你可以通过引用来控制对象,但是引用改变了,不影响对象。这里是把引用改变了但是原来的String对象没有变化,只是你不能通过s这个引用来访问它了。
    第二三个问题就是java方法调用传值的特点:把引用传递给方法以后,方法内部会重新生成跟传入引用的副本,就相当于方法内部“克隆”出来个传入一样的引用,它俩指到同一个对象上面,所以可以通过“克隆”出来的引用来改变原对象的内容问题三,但是对于问题二你是把“克隆”出来的引用重新指向了,但是不会影响原来的引用。
      

  5.   

    String是不可变的,如果出现+或者拼接的话都是重新建的一个,而是改变原来的,所以就会有三个,所以如果多的话还是用StringBuilder性能好很多。
    String是属于对象,对象是引用,是将对象的地址传过去,而不是将值过去了。
    你理解为传值也可以,不过记住普通的是传值,引用的是传地址
      

  6.   

    1.你对s重新赋值了。s=s.contact("def"); 
    2.java是值传递的,你在operator里y=x,只改变的是operator方法里y的值,main方法里b还是指向“b”的
    3.交换了啊,你可以执行交换方法前也打印下
      

  7.   


    都没权限改自己回复下面补充下
    String的确是final的,一旦创建就不能改变,s.contact("def");执行这句后,“abc”还在String池中,而且创建了一个新的String" abcdef"  然后你通过赋值操作将s变量重新引用到了"abcdef",而不再指向原来的"abc"了,你可以试下不进行赋值操作,s的值就不会变了。
      

  8.   

    1.  s=s.contact("def"),你是创建了一个新对象,赋值为s+"def";如果你把 s=s.contact("def")改为s2= s.contact("def"),你就能发现s还是abc,而s2是abcdef;2. 原理同上,String是final类,值是不可改变的,你给String类赋另一个值,其实是创建了一个新的String类,在operate(String x,String y)方法中,x.contact(y)等于ab,但x依旧是啊,你如果写x=x.contact(y),则x就是ab,operate(String x,String y)中的方法当然起作用了,但String类是final的,所以在main方法中,输出结果依旧是a.b;你把2写成下面的样子再看public class J_String
    {
       public static void operate(String x,String y)
       {
       x = x.contact(y);
       y=x;
       System.out.println(x+"."+y);   }
       public static void main(String args[])
       {
       String a="a";
       String b="b";
       operate(a,b);
       System.out.println(a+"."+b);
       }}
    3. 3和2基本是一个问题,在swap(String s[])方法中的操作不影响main方法中的String类的值。
      

  9.   

    准确的来说,String 类分2种书写方式
       1. String s1=new String("a");//相当于new出一个对象s持有对它的引用
          String s2=new String("a");//又在堆内存new出一个对象,
          System.out.println(s==s);//输出false,==比较的是堆内存中2个对象的地址值
      ----------------------------------------------------------------------------------
       2. String s1="a";//new一个对象放到池里面
          String s2="a";//从池中寻找"a"对象赋给s2
          所有此时s2持有该对象的引用。
          System.out.println(s1==s2);//输出true
      
                     
         
      

  10.   

    第二题,因为这里的String作为基础类型,传参不能作为引用;在函数调用之中,a,b的值会变化,但是调用结束后,a,b的值恢复为进入函数调用之前的值
      

  11.   

    String的concat()方法产生一个新对象
    public String concat(String s)
        {
            int i = s.length();
            if(i == 0)
            {
                return this;
            } else
            {
                char ac[] = new char[count + i];//构建字符序列
                getChars(0, count, ac, 0);//复制原来的字符序列
                s.getChars(0, i, ac, count);//添加新的字符序列
                return new String(0, count + i, ac);//用构建好的字符新序列创建一个String对象并返回
            }
        }
    所以每次调用String对象的concat方法必须获取方法返回的新对象。