解决方案 »

  1.   

    先理解这个:方法传参是值的一个副本.
    所以,一个个参数是String类型,String是引用类型,str指向一个String对象good,String是final类型,所以方法里的str是str引用的一个拷背(两个str不是同一个对象),因为String是final类型,所以方法里的" test ok";其实是新创建的另一个对象,和"good";不是同一个对象.所以并没有改变原来的值.同理方法里的ch也是ch引用的一个拷背(两个引用不是同一个对象),但是两个引用指向的是同一个对象{ 'a', 'b', 'c' },所以会改变原来的值.
      

  2.   

    java当中都是值传递的。当一个对象[A]被当做参数传递以后,只是将对象[A]的一个副本传递给了方法。
    原本对象[A]和副本对象[A]都指向同一块地址,当副本对象[A]被指向了一个new的对象,则副本对象[A]指向地址就变了,而原本对象[A]还是在指向原来的地址。
    原本对象ch[]和副本对象ch[]也是指向同一块地址,但是ch[0]是对地址中的值进行操作,所以当ch[0]被改变时,原本对象ch[]和副本对象ch[]指向的同一块地址中记录的值就被改变了。总结一点就是:值改变和地址改变。具体请参考:http://www.cnblogs.com/clara/archive/2011/09/17/2179493.html
      

  3.   

    恩恩,有点懂了,但是为什么String要设计成final的呢?
      

  4.   

    恩恩,有点懂了,但是为什么String要设计成final的呢?
    这个问题问得好,看看这篇文章你就明白为什么要这样设计了
    http://blog.csdn.net/renfufei/article/details/16808775
      

  5.   

    感觉三楼的有道理,2楼的final感觉说错了。
      

  6.   

    三楼说的对   ,是值改变和地址的转换         二楼哪final  完全没听过
      

  7.   

    给楼主增加一下难度:
    public static void main(String[] args) {      
    StringBuilder str1=new StringBuilder("AAA");
    StringBuilder str2=new StringBuilder("BBB");
    StringBuilder str3=new StringBuilder("CCC");
    change(str1,str2,str3);
    System.out.println("str1是:"+str1);
    System.out.println("str2是:"+str2);
    System.out.println("str3是:"+str3);
    }
    public static void change(StringBuilder str1,StringBuilder str2,StringBuilder str3) {  
    str3=str1;
    str1=str2;
    str2=str3;
    str1.append("1");
    str2.append("2");
    }
      

  8.   

    String对象一个重要的特性就是永久性(定长的),一旦创建就不能被改变,让一个字符串发生变化,其实就是引用了另外一个字符串,比如String str =“abc”;System.out.println(str.hashCode());str="bcd";System.out.println(str.hashCode());显然不可能对同一个对象引用。
      

  9.   

    一个个参数是String类型,String是引用类型,str指向一个String对象good,String是final类型,所以方法里的str是str引用的一个拷背(两个str不是同一个对象),因为String是final类型,所以方法里的" test ok";其实是新创建的另一个对象,和"good";不是同一个对象.所以并没有改变原来的值.同理方法里的ch也是ch引用的一个拷背(两个引用不是同一个对象),但是两个引用指向的是同一个对象{ 'a', 'b', 'c' },所以会改变原来的值.
      

  10.   

    其实关于String的一共有3个  String是定长的  ,StringBuffer是可变长的且线程同步, StringBuider是可变长的且线程不同步
      

  11.   

    其实有没有final都一样,“good”就是一个String类的常量对象
      

  12.   

    答案是:
    str1是:AAA2
    str2是:BBB1
    str3是:CCC最后的结果是str1的副本指向了str2所指的对象,str2和str3的副本都指向了str1所指的对象
    谢谢你!
      

  13.   

    跟javascript一样
    public void change(String str, char ch[]) {
            //str.value =" test ok";    //如果这样就可以了,但value是private;
            str = " test ok";
            ch[0] = 'g';
        }
      

  14.   

    两点:1.。String 是final的,每次改变都是重新创建对象。
    2.  java中只有值传递没有引用传递。
    记住吧
      

  15.   

    change函数里面把str="test ok"换成this.str="test ok",就可以得到你认为的值了,函数里面的str修改的应该是形参的吧,所以是形参引用指向了一个新的对象,而不是类里面的str引用指向了一个新对象
      

  16.   

    答案是:
    str1是:AAA2
    str2是:BBB1
    str3是:CCC最后的结果是str1的副本指向了str2所指的对象,str2和str3的副本都指向了str1所指的对象
    谢谢你!  既然str1的副本又指向了新的地址,那岂不是str1的值不会放生变化?  既然str2和str3的副本都指向了str1所指的对象,那为什么str2 和str3 的值不一样?求解,谢谢
      

  17.   


    public class Example {
        String str = new String("good");
        char[] ch = { 'a', 'b', 'c' };
     
        public static void main(String[] args) {
            Example example = new Example();
            example.change(example.str, example.ch);
            System.out.print(example.str + " and ");
            System.out.println(example.ch);
        }
     
        public void change(String str, char ch[]) {
            str = " test ok";
            ch[0] = 'g';
        }
    }之前也许我表达的不对,我用我的理解给说明一下吧,一步步来。
    首先,str和ch都是引用类型,所以
    String str = new String("good");
    char[] ch = { 'a', 'b', 'c' };
    其实是一个str引用对象指向它的实际对象“good”;一个ch引用对象指向了它的实际对象{ 'a', 'b', 'c' };(java里所有的都可以叫对象)
    str-->"good"    ch-->{ 'a', 'b', 'c' }
    其次,方法传值传的是值拷背,也就是方法里的参数传到方法内部后,是参数的一个副本。所以public void change(String str, char ch[]) {
            str = " test ok";
            ch[0] = 'g';
        }这里的str(方法)是外面str的一个拷背,ch(方法)是外面ch的一个拷背。因为是拷背,所以指向一样。因此有
    str-->"good"    ch-->{ 'a', 'b', 'c' }
    str(方法)-->"good"    ch(方法)-->{ 'a', 'b', 'c' }
    最后,在方法里str(方法)这个引用对象又指向了另一个实际对象  str(方法) = " test ok";,所以有
    str-->"good"    ch-->{ 'a', 'b', 'c' }
    str(方法)-->" test ok"    ch(方法)-->{ 'a', 'b', 'c' }
    而ch(方法)并没有重新指向另一个实际对象,只是对它现在指向的对象的值做了改变,也就是对原来的实际对象的值做了改变。
    换句话说,如果方法里加一段代码 ch(方法) = { 'g', 'b', 'c' } 这样 public void change(String str, char ch[]) {
            str = " test ok";
            ch = { 'a', 'b', 'c' };//加的代码,表示指向另一个实际对象
            ch[0] = 'g';
        }ch(方法)就和str(方法)一样,指向了另一个实际对象,这时候无论你怎么操作方法里的ch(方法)和str(方法),都不会影响到方法外的ch和str,输出结果就是两个都不变。
    总结,前面我说的String是final和这个问题不大,我在这里向楼主和各位大侠道歉。话有点啰索,希望有帮助。
      

  18.   

    第一个只是把str的引用传递给它,并没有在实质上改变str引用的值,第二个则是把内存中的str[0]改变,是实质上的。
      

  19.   

    这样对比来看会不会清楚一些呢public class Test { /**
     * @param args
     */
    public static void main(String[] args) {      
    StringBuilder str1=new StringBuilder("AAA");
    StringBuilder str2=new StringBuilder("BBB");
    StringBuilder str3=new StringBuilder("CCC");
    change(str1,str2,str3);
    System.out.println("str1是:"+str1);
    System.out.println("str2是:"+str2);
    System.out.println("str3是:"+str3);
    }
    public static void change(StringBuilder a,StringBuilder b,StringBuilder c) {  
    c=a;
    a=b;
    b=c;
    a.append("1");
    b.append("2");
    System.out.println("a是:"+a);
    System.out.println("b是:"+b);
    System.out.println("c是:"+c);
    System.out.println("-------------------------");
    }}
      

  20.   


    public class Example {
        String str = new String("good");
        char[] ch = { 'a', 'b', 'c' };
        int abc = 12;
     
        public void change(String str, char ch[]) {
         str = " test ok";
         ch[0] = 'g';
    //     char[] ch1 = {'g','g','g'};
    //     ch = ch1;
        }
        
        public static void main(String[] args) {
            Example example = new Example();
            example.change(example.str, example.ch);
            System.out.print(example.str + " and ");
            System.out.println(example.ch);
        }
     
    }result:good and gbc
      

  21.   


    public class Example {
        String str = new String("good");
        char[] ch = { 'a', 'b', 'c' };
        int abc = 12;
     
        public void change(String str, char ch[]) {
         str = " test ok";
    //     ch[0] = 'g';
         char[] ch1 = {'g','g','g'};
         ch = ch1;
        }
        
        public static void main(String[] args) {
            Example example = new Example();
            example.change(example.str, example.ch);
            System.out.print(example.str + " and ");
            System.out.println(example.ch);
        }
     
    }result:good and gbc
      

  22.   


    public class Example {
        String str = new String("good");
        char[] ch = { 'a', 'b', 'c' };
        int[] abc = {1233,12};
     
        public void change(String str, char ch[],int[] abc) {
         str = str.replace("g", "x");
         str = " test ok";
         char[] ch1 = {'g','g','g'};
         ch = ch1;
         ch[0] = '2';
         abc[0] = 1235;
        }
        
        public static void main(String[] args) {
            Example example = new Example();
            example.change(example.str, example.ch,example.abc);
            System.out.print(example.str + " and ");
            System.out.println(example.ch);
            System.out.println(example.abc[0]);
        }
     
    }当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递? 
        答:是值传递。Java 编程语言只有值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是该对象的引用一个副本。指向同一个对象,对象的内容可以在被调用的方法中改变,但对象的引用(不是引用的副本)是永远不会改变的。
    Java参数,不管是原始类型还是引用类型,传递的都是副本(有另外一种说法是传值,但是说传副本更好理解吧,传值通常是相对传址而言)。
        如果参数类型是原始类型,那么传过来的就是这个参数的一个副本,也就是这个原始参数的值,这个跟之前所谈的传值是一样的。如果在函数中改变了副本的 值不会改变原始的值.
        如果参数类型是引用类型,那么传过来的就是这个引用参数的副本,这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址,而是改变了地址中的 值,那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址,如new一个,那么副本就指向了一个新的地址,此时传入的参数还是指向原来的 地址,所以不会改变参数的值。