StackTc 2018-01-27 12:11 采纳率: 90.9%
浏览 4171
已采纳

String引用的值改变了为什么赋值的值没变

代码跟运行结果如下

 public static void main(String[] agrs){
        String s1 = new String("aaa");
        String s2 = s1;

        System.out.println("s1=" + s1);
        System.out.println("s2=" + s2);
        s1 = "bbb";
        System.out.println("s1=" + s1);
        System.out.println("s2=" + s2);

    }
s1=aaa
s2=aaa
s1=bbb
s2=aaa
  • 写回答

14条回答 默认 最新

  • baskar 2018-01-27 14:37
    关注

    引用https://www.zhihu.com/question/20618891
    string是不可变的引用类型,赋值时等于是将新的字符串值得引用指向到变量名,每写一个新的字符串值就会在内存开辟新的地址存放这个值

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
  • daiboyu 2018-01-27 12:18
    关注

    String s2 = s1; 是拷贝赋值,不是引用。

    评论
  • lyter1214 2018-01-27 12:30
    关注

    编译器优化引起的,new一个固定字符串编译器按常量处理,s1重新赋值后指向另外一个内存区域,s2还是指的aaa这个常量区

    评论
  • timlcy 2018-01-27 12:38
    关注

    首先

     String s1 = new String("aaa");
    

    这条语句是在静态区内创建了一个aaa的常量,然后在创建s1指向'aaa'常量

     String s2 = s1;
    
    

    这条语句指的是s2指向'aaa'的地址
    虽然s1被改,但s2并没有重新指向新的地址

    评论
  • threenewbee 2018-01-27 12:47
    关注

    字符串是不变的(immutable)
    s1 = "bbb";
    不能改变原来s1的内容为bbb
    相反,它创建了一个新的字符串(无论是在常量池还是堆栈),并且让s1指向了这个新的字符串。
    而s2还指向bbb

    评论
  • Solming 2018-01-27 12:55
    关注

    简单来说就是s2是已经把s1的内容存在自己的内存区域,s1和s2分别有两个地址,打印重新给s1赋值只是在s1的地址的内容进行修改

    评论
  • zg97zb 2018-01-27 12:55
    关注

    s1 s2 都只是常量aaa的“名字”。当执行s1=bbb时 s1又被bbb用来当"名字"。此时aaa的名字就只剩s2,所以此时打印出来的是原来内容

    评论
  • leoluoxu 2018-01-27 13:43
    关注

    程序有上往下执行,当执行第一个赋值的时候S1的值给了S2,当S1发生了改变是改变了地址,所以S2的值不会随之改变。

    评论
  • 老兵新唱 2018-01-27 14:04
    关注

    之所以没有被改变和String的构造方法有关系,基本上String都是拷贝赋值的。

    下面链接说的已经很清楚了,可以读一下。
    https://www.cnblogs.com/JavaSubin/p/5450849.html

    评论
  • y272451590 2018-01-27 14:22
    关注

    赋值和赋址本质上都是赋值(只是对于引用类型值就是地址)
    对于字面量在编译后字节码总是从常量池进行引用,在编译后相同字面量在运行时引用是一样的

    评论
  • qq_36343297 2018-01-27 15:49
    关注

    string s1 = new string("aaa"); 在内存空间创建字符串“aaa”,并创建字符串引用变量s1指向它;
    string s2 = s1; 创建字符串引用变量s2,赋值s1,表示s2和s1指向相同的内存空间;
    s1 = "bbb"; 相当于在内存空间创建字符串常量“bbb”, 用已有的s1指向它,现在s1不在指向原来的"aaa";
    而s2的指向没有变,还是指向"aaa". 所以输出的内容还是aaa。

    如果想让s2指向的内存和s1一致,应该在修改s1的指向之后再做一次 s2=s1;
    这时内存空间中的字符串“aaa”已经没有引用指向它,在java中会被垃圾回收站回收,但c++没有垃圾回收功能,可能会造成内存泄漏

    评论
  • 木鱼Gavin 2018-01-27 16:07
    关注

    图片说明

    评论
  • lpb113625 2018-01-28 01:51
    关注

    当String s1=new String(“aaa”)时,是在堆内存中开辟一块空间存储aaa,再在绽内存中开辟一块空间放变量s1,然后让s1指向aaa,改变s1的值,只是在栈内存中再声明一个产量让其指向aaa

    评论
  • Lucky_SS 2018-02-02 07:06
    关注

    第一次的时候 s1和s2的引用是想同的 值肯定相同

    第二次你对s1再次赋值了 s2还是引用的原来的值

    所以不一样了

    评论
查看更多回答(13条)

报告相同问题?

悬赏问题

  • ¥30 宾馆客房管理系统可视化
  • ¥20 unity打光没有照亮物体
  • ¥25 powershell如何拷贝1周前的文件
  • ¥15 询问MYSQL查询SQLSERVER数据表并比较差异后,更新MYSQL的数据表
  • ¥15 关于#前端#的问题,请各位专家解答!
  • ¥15 最小生成树问题 Prim算法和Kruskal算法
  • ¥25 医院住院病人呼叫器设计
  • ¥15 不想和现在的团队合作了,怎么避免他们对程序动手脚
  • ¥20 C语言字符串不区分大小写字典排序相关问题
  • ¥15 关于#python#的问题:我希望通过逆向技术爬取1688搜索页下滑加载的数据