zoukankan      html  css  js  c++  java
  • Java中的字符串

    字符串缓冲池

    public  class TestString {
    	public static void main(String[] args){
    		String str1 = "string";
    		System.out.println(System.identityHashCode(str1));
    		String str2 = "string";
     		System.out.println(System.identityHashCode(str2));
     	}
    }
    

    ​ System.identityHashCode()是根据内存地址算Hash值,运行上面代码两次输出的结果一致,这说明str1与str2指向的内存地址是一样的。因为JVM将字符串常量放在了一个叫字符串缓冲区的,因为str1和str2的值一样,所以在缓冲区放一份就可以,同时str1和str2都指向这个地方。

    ​ 当然str1="testString"、str2="test" + "String",str1与str2也会指向相同的区域。因为在编译java文件时,会将str2的值合为"testString"。但是如果str3="String",str2 = "test"+ str3时,str2将和str1虽然内是相等的,但是str1和str2指向的内存地址不同,因为编译器不会将变量str3转换为“String",不过也有下面的特例

    public  class TestString {
    	public static void main(String[] args){
    		String str1 = "TestString";
    		System.out.println(System.identityHashCode(str1));
     		final String str3 = "Test";
     		String str2 = str3 + "String";
     		System.out.println(System.identityHashCode(str2));
     	}
    }
    

    ​ 执行上面的代码会发现输出的值是相等的,这是因为我们在变量str3前加了关键字final,该关键字相当于C中宏替换,告诉编译器编译的时候将str3都替换成"Test",所以才会有str1与str2相等(指向同一内存区)。

    String类不可变字符串

    String类的底层是用数组实现的,我们知道数组的长度确定好后是不能更改的

    str = "abc";
    str = str + ”defg“;
    

    Java中对于上面的处理过程是重新创建一个对象,并将内容初始化为”abcdefg“,再让str指向这个新的对象。而“abc”依然在字符串缓冲区,如果在后面不会用到,并且垃圾回收器不回收字符串缓冲区的数据的话,就会发生内存泄露问题。

    字符串动态扩展

    如果字符串要动态扩展的话建议使用StringBuilder或者是StringBuffer,前者非线程安全,后者线程安全,用法如下:

    public  class TestString {
    	public static void main(String[] args){
    	    StringBuilder sb = new StringBuilder("TestString");
            System.out.println(System.identityHashCode(sb));
            sb.append("String");
            System.out.println(System.identityHashCode(sb));
            System.out.println(sb);
            StringBuffer sb2 = new StringBuffer("TestString");
            System.out.println(System.identityHashCode(sb2));
            sb2.append("String");
            System.out.println(System.identityHashCode(sb2));
            System.out.println(sb2);
     	}
    }
    

    + 的重载与 StringBuilder

    public class Concatenation {
        public static void main(String[] args) { 
            String mango = "mango"; 
            String s = "abc" + mango + "def" + 47; 
            System.out.println(s);
        } 
    }
    

    上面的代码在给字符串s赋值时,Java编译器会对其优化,采用StringBuilder将"abc"、mango、"def"以及47拼接起来,然后转换为String对象赋值给s。这样避免生成多个String对象从而浪费内存。

  • 相关阅读:
    python 类继承演示范例的代码
    C#监控指定目录的文件变化的代码
    如何开启红米手机4X的ROOT超级权限
    C# 发送电子邮件源码片段
    android中使用afinal一行源码显示网络图片
    (详细)华为畅享7 SLA-AL00的usb调试模式在哪里打开的流程
    C#自定义FTP访问类的代码
    C#的String.Split 分割字符串用法详解的代码
    红米Note 5A完美卡刷开发版获得ROOT超级权限的方法
    C# 类如何声明索引器以提供对类的类似数组的访问的代码
  • 原文地址:https://www.cnblogs.com/xidongyu/p/12237076.html
Copyright © 2011-2022 走看看