Java String pool 字符串池

这一篇写的很好了,我只是简化并且扩展一下,侵删
https://www.journaldev.com/797/what-is-java-string-pool
这一篇分析的有深度,参考
https://explainjava.com/java-string-pool/
这一篇是中文的,也不错
https://www.cnblogs.com/fangfuhai/p/5500065.html

字符串是不可变的

  • Java 的设计者认为,共享字符串(比如用于字符串的比较)的效率要比修改字符串的效率更加重要,所以把String设计为不可变的。

字符串池

  • Java字符串池存储在堆内存中,它可以被垃圾回收
  • 当使用引号创建字符串时,会先查找字符串池看是否有相同值的字符串,如果有了就返回只字符串池中的引用,没有就新创建一个再返回 新创建字符串的引用
  • 当然我们可以使用new在堆中开辟新的空间,开辟完成之后又可以使用intern()方法让其进入字符串池
  • 要注意的是,只有字符串常量是共享的,而字符串运算的操作的结果如+,subString()等不是共享的
    在这里插入图片描述
    下面的例子可以证明上面的几条观点
/**
* test
*/
public class Test {

   public static void main(String[] args) {
       String str1 = "hello";
       String str2 = "hello";

       System.out.println(str1 == str2); // true

       System.out.println(new String("hello") == str1); // false
       System.out.println(new String("hello").intern() == str1); // true

   }
}

+的执行时期

看一下这一条


/**
* test
*/
public class Test {

   public static void main(String[] args) {
       String str1 = "hello";
       String str2 = "hello";

       System.out.println((str1 + "") == str2); // false
       System.out.println("hello" + "" == str2); // true

   }
}

为什么用引用与字符串常量进行+运算和字符串常量之间直接进行+运算结果不同呢?
因为两个+的执行时间不同!
字符串量"+“拼接是在编译期间进行的,拼接后的字符串存放在字符串池中,而字符串引用的”+"拼接运算实在运行时进行的,新创建的字符串存放在堆中的其他地方。

这样下面这一条也能解释了


/**
* test
*/
public class Test {

   public static void main(String[] args) {
       System.out.println("helloo".substring(0, 5) == "hello"); // false
       System.out.println("hello" + "" == "hello"); // true
   }
}

自然也是因为方法和+执行的时间不同

字符串池的优点

  • 字符串池最主要的优点就是节省了内存的开销

字符串池的实现

  • Hashmap

字符串池欺骗

如果你用的是JDK8, 看个厉害的…(没啥用)

import java.lang.reflect.Field;
 
public class StringPool {
 
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
        // add "Hello" to pool
        String hello = "Hello";
 
        Field value = hello.getClass().getDeclaredField("value");
        value.setAccessible(true);
        value.set(hello, "Buy buy".toCharArray());
   
        System.out.println("Hello"); // Buy buy
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值