String s1 = "a";
String s2 = s1;
s2 = "b";
System.out.println(s1); 也是a

解决方案 »

  1.   

    String s1 = "a";//这里的s1的值就是"a"了
    String s2 = s1;  //这句话是说吧s1的值赋给s2,也就是说s2的值也是"a"了然后你打印s2,不是"a"  还能是什么?
      

  2.   

    不是说他们的内存地址是一样的吗?S2=S1 这是只是把内存中的地址给了s2,
      

  3.   

    s2 本来就给给它赋的 a,为什么不是a?
    s1 重新赋值了肯定就是 b 啊,怎么会输出a
      

  4.   


    这样赋值的话  当int来看 不知道这样说正确否
      

  5.   

    刚刚看了篇文章感觉是这样 , 你们觉得对不对?String 类是final修饰的,也就是说当我把s1重新赋值的时候s1在内存中的地址就变了??
      

  6.   


    这样赋值的话  当int来看 不知道这样说正确否好像是吧?我基础不行啊。
      

  7.   

    Quote: 引用 12 楼 u011559804 的回复:

    值传递  木有指针
    没懂,大神详解
      

  8.   

    这个想了一下可以这样理解:
    首先String s1 = "a";是将"a"放入字符串驻留池同时指向"a"的引用,String s2是指向字符串驻留池的"a"引用,而不是s1的内存地址;
    当s1 = "b";是将"b"放入字符串驻留池同时指向"b"的引用,而这时s2还是指向字符串驻留池的"a"引用。
      

  9.   

    s1="b";
    为 s1 变量 重新赋值!
    就和 String s1 = "a"; 一个意思
    s2=s1 是
    赋值! 将 s1 指向的内存地址穿过去了。
    。s2 不是依赖s1.
    而是直接指向了"a" 的内存地址。
    传递的是引用。
      

  10.   

    楼主看看String 和StringBuffer区别就立马明白了为什么是这样子的。。求分
      

  11.   

    栈中先建一个引用对象s1,指向一个内存地址,这个地址的值为a
    然后再建一个引用对象s2, 指向s1的引用,也就是s1指向的内存地址,也就是a
    s1 和 s2 共同指向了一个具体的内存地址。
    这时,将s1 指向的地址的值改为b
    那么他们指向同一个地址,s2也就是b了。
      

  12.   

    当后面s1="b"时,改变的只是s1的地址,但是没有改变s2的地址,所以这时候的s1与s2的地址是不一样的,如果你在s2=s1,s2的值就是b了
      

  13.   

    String s1 = "a";
    String s2 = s1;
    s1 = "b";
    System.out.println(s2);
    不知道楼主学的是什么语言;我学的是java;就从Java方面解释下,首先java里的字符类有个常量池的概念,如果常量池没有“a”这个字符的话就创建这个对象同时在堆里创建一个引用对象s1,并且把字符a放入常量池里。
    第二行代码是把s1在堆中的内存地址赋值给s2,此时s2的内存地址指向的就是常量池中的“a”.第3行代码中的字符“b”和字符“a”一样的创建方式,并且在堆中分配新的物理内存地址给s1,此时的字符“b”的引用对象s1所指向的内存地址已经和前面的内存地址不同了。所以打印s2自然会打印s2内存地址所对应的值“a”.
      

  14.   

    这是"写入时拷贝" COpyOnWrite  
      

  15.   

    用C的理解方式解释下,不知道对不对。
    char *s1 = "a";
    char *s2 = s1;
    s1 = "b";
    printf("%s", s2);
    printf("%s", s1);s1,s2作为局部变量放在堆栈区,字符串a,b放在只读段。
    s1,s2仅仅是变量而已,所谓指针,也只是一个指针类型的变量。第一行,s1指向字符串a的内存地址,
    第二行,s1把地址值赋值给s2,S2也指向字符串a
    第三行,s1指向字符串b的内存地址
    第四行,打印S2,当然打印的是字符串a了
    第五行,打印S1,当然打印的是字符串b了下面是我用的C#写的测试代码,现在没搞C了。
      

  16.   

        class Program
        {
            static void Main(string[] args)
            {
                string s1 = "a";
                string s2 = s1;
                s1 = "b";
                Console.Write("s2 = "s2);
                Console.Write("s1 = "s1);
                Console.Read();
            }输出结果s2 = a, s1 = b.
      

  17.   

    String s1 = "a"; // s1引用"a"对象
    String s2 = s1; // s2引用s1引用的对象,即,s2引用"a"对象
    s1 = "b"; // s1现在引用"b"对象(但是s2没有变化对吧)
    System.out.println(s2); // s2还是引用"a"对象,打出a// 如果“引用”这个词还不好理解,请把它改成“指向”,并在纸上画出这种指向的关系。String s1 = "a"; // s1指向"a"对象
    String s2 = s1; // s2指向s1指向的对象,即,s2指向"a"对象
    s1 = "b"; // s1现在指向"b"对象(但是s2没有变化对吧)
    System.out.println(s2); // s2还是指向"a"对象,打出aString s1 = "a"; // s1 -> "a"
    String s2 = s1; // s2 -> "a" <- s1,注意,不是s2 -> s1 -> "a"
    s1 = "b"; // s2 -> "a" s1 -> "b"
    System.out.println(s2); // so ...个人觉得问题的关键就是“如何解读=操作”。
      

  18.   


    这有啥好纠结的  
    第一句:把"a"在内存中的地址给赋值给s1
    第二句:把"a"在内存中的地址复制一份给s2,也就是此时s1、s2均指向内存中的"a"
    第三句:把"b"在内存中的地址赋值给s2,此时s2指向内存中的"b",而s1还是指向内存中的"a"
    所以打印出a
      

  19.   

    你这个是先已经给s2赋过值了啊   要是将s1 = "b";放在上面写 输出的是b
      

  20.   

    由于String是immutable的,为了便于理解,我使用如下代码片段进行对比(int[]是mutable的)
            int[] a = { 1, 2, 3, }; // a引用一个int[]对象,该对象为一个int array,三个元素1,2,3
            int[] b = a; // b引用a引用的那个对象,同一个对象
            b[0] = 0; // 修改b引用的那个对象(也就是修改了a引用的对象,是同一个对象来着)
            for (int i : a) {
                System.out.println(i); // a引用的对象变了,0,2,3
            }
      

  21.   

    ............................
    ............
    String是字胡窜的意思!
      

  22.   

    String s1 = "a";
    String s2 = s1;
    s1 = "b";
    System.out.println(s2);为什么输出a? 对象变量s1->对象值a
    对象变量s2->对象变量s1->对象值a 实际上 对象变量s2->对象值a
    对象变量s1->对象值b

    在这里如果对象变量s2->对象变量s1
    那么 对象变量s2->对象变量s1->对象值b   s2=b
    。。
    没有 那么。
    s2=a
    s1=b
      

  23.   


    楼主跟你画个图 你就明白了
    首先:
    然后是值传递  即s1把自己保存的内存地址复制一份给了s2
    然后s1再次赋值 把自己原来保存的"a"的内存地址换成了"b"的内存地址
    而s2保存的还是"a"的内存地址 
    所以输出s2是"a"
      

  24.   

    恩 是这样子的 楼主
    String s1 = "a";会牵扯到堆的概念吗,只会停留在栈上面吧。
    String s1 = "a"存放在常量池,常量池放在栈中,s1直接指向常量池的这块引用;
    如果String s1 = new String("a");才会牵扯到堆,在常量池创建“a”的同时在堆中开辟一块内存,这时才是s1指向堆中的内存地址,堆中的内存地址指向常量池中的"a"引用。
      

  25.   

    String s1 = "a";(1)
    String s2 = s1;(2)
    s1 = "b";(3)
    (1)行    s1是地址 在栈中,a是内容在内存中(堆),s1指向a
    (2)行   s2是地址 在栈中,s2=s1   s1的地址赋给s2,就是说s2也指向了a
    (3)行   s1=“b”,s1指向了b
    三句话执行下来,s2指向的是a  所以输出a。
    过程中s1只是指向的内容变了而已。
      

  26.   

    定义一个变量必须初始化后才能使用,初始化可以new一个新的对象,也可以将这个变量指向一个已经存在的变量。变量不是包含一个对象,只是引用一个对象。
    变量是一个指向对象的指针,一个对象包含另一个对象也是包含这个对象的指针。java 中如果这个指针没有初始化,会报错不会产生一个随机的结果。String s1 = "a"; //这是s1指向一个匿名对象“a”
    String s2 = s1;// 这里s2也指向这个匿名对象“a”,而不是指向S1
    s1 = "b";  这时候s1又指向匿名对象“B”, 而S2还是指向匿名对象“a”
    System.out.println(s2);java 中问什么会有普通克隆和深层 克隆的区别。普通的克隆只是给变量的分配了内存空间,对象里变量和原来的对象指向相同。
    深层 就是对象里变量也是新的