Java高级编程实验六---如何验证Java字符串的不变性,及使用StringBuffer减少内存的消耗

参考地址
有图有真相

验证不变性代码

String str = "Hello";  
  
System.out.println(str);//输出为Hello  
  
str.concat("World");//该方法是在原来的变量后面添加一个字符串然后变成新的字符串  
  
System.out.println(str);//输出为Hello 
  
str=str.concat("World");  
System.out.println(str);//输出为HelloWorld

就是指引用的对象实例的是不可以改变的,但是我们可以改变引用的地址,改变地址改变值。
常量池概念:

在Java虚拟机的整个体系里面,我们加载类文件,分别存放到不同的单元,占用大部分内存空间的是常量池,大约能占到60%,为了节省内存,JVM专门用一片特殊的存储区域存储String,作为String ,面对String常量,会检查String常量池中是否存在此常量,如果存在的话,直接进行引用,避浪费多余的内存空间,因此必须确保这个具体的常量不能变,这就是我们经常讲的String的不变性。

我们可以联想到其它方式,还有其它使用的技术:

String newStr=“java”;//这个应该是放在String的常量池中的常量。
String newStrObj=new String("java");//这个放在常规的内存中。

在这里插入图片描述
假若字符串对象允许改变,那么将会导致各种逻辑错误,比如改变一个对象会影响到另一个独立对象. 严格来说,这种常量池的思想,是一种优化手段.
请思考: 假若代码如下所示,s1和s2还会指向同一个实际的String对象吗?
String s1= “ab” + “cd”; String s2= “abc” + “d”;
也许这个问题违反新手的直觉, 但是考虑到现代编译器会进行常规的优化, 所以他们都会指向常量池中的同一个对象. 或者,你可以用 jd-gui 之类的工具查看一下编译后的class文件。

代码实现

import java.nio.charset.StandardCharsets;

public class Experiment6 {
    public static void main(String[] args) {
        //验证string类的不变性
        String s1 = "张李浩";
        s1.concat("在");
        System.out.println(s1);//输出"张李浩",说明引用对象的实例是不可以改变的
        s1 = s1.concat("做实验");//输出"张李浩做实验",可以改变引用的地址,改变地址改变值
        System.out.println(s1);
        //下面实现用StringBuffer, StringBuilder解决String类带来的消耗内存的问题,
        String s2="张";
        //查看字符串的内存地址
        System.out.println(s2.getBytes(StandardCharsets.UTF_8));
        String s3="李";
        System.out.println(s3.getBytes(StandardCharsets.UTF_8));
        String s4="浩";
        System.out.println(s4.getBytes(StandardCharsets.UTF_8));
        s2=s2+s3+s4;
        System.out.println(s2.getBytes(StandardCharsets.UTF_8));//总共占用了4个内存地址
        //使用StringBuffer和StringBuilder提供的append方法解决内存消耗过大问题
        StringBuffer b1=new StringBuffer("张");
        System.out.println(b1);
        b1.append("李浩");
        //StringBuffer和StringBuilde对象调用append方法拼接好字符串后,临时字符串变量就会被当作垃圾释放掉了,有效地节省了内存空间。
        System.out.println(b1);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值