class Test2 {
    String a = "1";
    String b = "2";
}
public class NoUpdate {
    public static void changeUpd(Test2 t) {
        t.a = "abc";
        t.b = "123";
    }
    public static void main(String[] args) {
        Test2 t2 = new Test2();
        changeUpd(t2);
        System.out.println(t2.a + "----" + t2.b);
    }
}这个程序输出 abc----123 ;
但是如果修改一下,
publicclass Test1 { 
   
    publicstaticvoid changeStr(String str){ 
        str="welcome"; 
    } 
    public static void main(String[] args) { 
   
        String str="1234"; 
        changeStr(str); 
        System.out.println(str); 
    } 

这里就输出 1234 
同样传递的是对象,为什么第二个程序的值没有被修改呢?两个程序传递的参数都应该是原对象的引用的,为什么?想不明白,呵呵

解决方案 »

  1.   

     public static void changeStr(String str){ 
            str="welcome"; 
    }
       可以试试不要void,让它return str; 
      

  2.   

    java传参的时候,基本数据类型是按值传递,对象类型是按引用传递
    String是对象,应该是按引用传递,但是String是一种特殊的对象,即他所引用的值是无法改变的
    一开始的时候main方法中的str所引用的对象是"1234",当执行到changeStr(str)时,会把changeStr中的str指向"1234",这时候内存中有两个str,所引用的内容都是"1234",在往下,让changeStr中的str引用"welcome",注意这里要提到String对象的一个特性,即他的内容是无法改变的,起初str = "1234",当str = “welcome”时,并没有将1234换成welcome,而是重新分配一个内存存储"weilcome",然后让str引用该内容,而main中的str依然引用的是"1234"
      

  3.   

    lz可以试试把代码中的String换成StringBuffer或者StringBuilder,就会发现结果输出的是welcome,因为StringBuffer是可以改变所引用的内用的,而不是重新分配内存
    因此我们编程的时候,如果需要频繁的改变字符串内容,应该考虑使用StringBuffer或者StringBuilder(两者的区别在于前者是线程安全的,对于一个线程的情况,用StringBuilder效率更高),以节省内存空间,
      

  4.   

    class Test2 { 
        String a = "1"; 
        String b = "2"; 

    public class NoUpdate { 
        public static void changeUpd(Test2 t) { 
            t.a = "abc"; 
            t.b = "123"; 
        } 
        public static void main(String[] args) { 
            Test2 t2 = new Test2(); 
            changeUpd(t2); 
            System.out.println(t2.a + "----" + t2.b); 
        } 
    } 这里在内存堆里的对象是t2,你改变的是对象里的内容。
    publicclass Test1 { 
      
        publicstaticvoid changeStr(String str){ 
            str="welcome"; 
        } 
        public static void main(String[] args) { 
      
            String str="1234"; 
            changeStr(str); 
            System.out.println(str); 
        } 
    } 这里的对象是str,你修改的也是str。
      

  5.   

    因为String对象的值一旦创建是不可改变的。String类是个final类。
      

  6.   


    public static void main(String[] args) {
    String a = "a";
    a = "b";
    System.out.println(a);
    }
    你说a是多少
      

  7.   

    final class Test2 {
        String a = "1";
        String b = "2";
    }public class NoUpdate {
        public static void changeUpd(Test2 t) {
            t.a = "abc";
            t.b = "123";
        }    public static void main(String[] args) {
            Test2 t2 = new Test2();
            changeUpd(t2);
            System.out.println(t2.a + "----" + t2.b);
        }
    }楼上你在试试这个,并不是final的原因。
      

  8.   

    class Test2 { 
        String a = "1"; 
        String b = "2"; 

    public class NoUpdate { 
        public static void changeUpd(Test2 t) { 
            t.a = "abc"; 
            t.b = "123"; 
        } 
        public static void main(String[] args) { 
            Test2 t2 = new Test2(); //a=“1”,b=“2”
            changeUpd(t2); //a="abc",b="123"
            System.out.println(t2.a + "----" + t2.b); //打印
        } 

    这个程序输出 abc----123 ; 
    但是如果修改一下, 
    public class Test1 { 
      
        public static void changeStr(String str){ 
            str="welcome"; 
        } 
        public static void main(String[] args) { 
      
            String str="1234"; //主函数中的str=“1234”
            changeStr(str); changeStr中的“welcom”被改为“1234”,但是主函数中的值没被改变
            System.out.println(str); //输出主函数中的值是“1234”
        } 

    这里就输出 1234
    lz说的“两个程序传递的参数都应该是原对象的引用的”,你引用的没错,不过传值并不是一样的
      

  9.   

    String类是什么呢!final的第二例子中   publicstaticvoid changeStr(String str){
            str="welcome";
        } 相当于:   publicstaticvoid changeStr(String str){
            str= new String("welcome");
        } 所以,传参都是引用值的复制, 任何引用传递进来之后,如果重新分配一个new 对象,都仅仅发生在复制过来的引用参数上,对原来对象不会产生任何作用,除非是这样的:   publicstaticvoid changeStr(MyClass a){
            a.attribute = "12123";//注意不是new哦!
        } 我之前做了一个比较完善的总结,希望对你有帮助:http://blog.csdn.net/ostrichmyself/archive/2009/10/03/4630976.aspx
      

  10.   

    楼上的你没看懂我的意思么? 两次传入的都是对象类型,传入String时,虽然String被修改了,但是打印的还是原来的String ,当传入其他类型对象时,被修改后就打印出被修改后的对象的值。
      

  11.   


    public class Test1 {
     
        public static void changeStr(String string){
            ;//这个时候string和str都引用的是相同的内存地址,其内容是"1234"
            string="welcome";//这个时候,不会把"1234"的内容改为"welcome",而是重新分配一块内存存储"welcome",并让string引用该内存,而主函数中的str仍然引用原来的"1234"。这是因为String对象是final的,其内容是无法改变的,只能重新分配内存空间存储新的内容
        }
        public static void main(String[] args) {
     
            String str="1234"; //主函数中的str=“1234”
            changeStr(str); //
            System.out.println(str); //输出主函数中的值是“1234”
        }
      

  12.   

    根本不是final的问题,看我10楼贴。
      

  13.   


    String的底层实现是其实是字符型数组,并且该数组也是final的
      

  14.   


    这里当然会改变, 你应该好好看看大家的回复了, 如果NoUpdate改成:
     public class NoUpdate {
         public static void changeUpd(Test2 t) {
             t = new Test2();
             t.a = "abc";
             t.b = "123";
         }
    你再调用试试! 没有改变, 结果还是"1"和"2"了,String a= "welcome" 的作用就是a = new String("welcome");
      

  15.   

    public final class String
        implements java.io.Serializable, Comparable<String>, CharSequence
    {
        /** The value is used for character storage. */
        private final char value[];    /** The offset is the first index of the storage that is used. */
        private final int offset;    /** The count is the number of characters in the String. */
        private final int count;    /** Cache the hash code for the string */
        private int hash; // Default to 0
    *************************************************
    上面是用jad反编译之后得到的源代码,可以看到String其实就是final char value[],因为是final的,所以他的值一旦被确定之后就无法改变,而你写的那个例子如果String a和String b都声明为final,你的代码就错了……
      

  16.   


    服了,这和final没关系,我知道String是final类型的,你仔细看了我10楼的例子在说。我晕啊。
    final class Test2 {
        String a = "1";
        String b = "2";

    这里已经声明为final了。
      

  17.   

    你这个final有意义么?你又不去……
    人家final指的是private final char value[]; 这句好不好