补坑:Java的字符串String类(3):再谈String

不太熟悉字符串的可以看看这两篇文章

补坑:Java的字符串String类(1)-CSDN博客

补坑:Java的字符串String类(2):一些OJ题目-CSDN博客

字符串创建对象

    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        String s3 = new String("hello");
        String s4 = new String("hello");
        System.out.println(s1 == s2); // true
        System.out.println(s1 == s3); // false
        System.out.println(s3 == s4); // false
    }

 

观察上面的代码,和debug结果。为什么s1=s2,而四个字符串的value和hash值相同的情况下s1!=s3, s3!=s4呢?

这就需要提到一个概念:字符串常量池

为了使程序的运行速度更快、 更节省内存Java8种基本数据类型和String类都提供了常量池

那什么是“池”呢?

“池”是编程中一种重要的提升效率的方式

比如家里向我们打生活费,有两种方法

方法1:每月定时打生活费,有可能会晚,有时候还需要我们向家里人开口要,效率很低

方法2:存到银行卡,把一年的生活费打到卡里,自己随时都可以取用

这里的方法2其实就是“池”的一种体现

为了节省存储空间以及程序的运行效率, Java 中引入了:
1. Class 文件常量池 :每个 .Java 源文件编译后生成 .Class 文件中会保存当前类中的字面常量以及符号信息
2. 运行时常量池 :在 .Class 文件被加载时, .Class 文件中的常量池被加载到内存中称为运行时常量池,运行时常
量池每个类都有一份
3. 字符串常量池

这篇文章我们主要讲字符串常量池


字符串常量池

JVM中的StringTable类,就是一个固定大小的HashTable

那什么样的会放入常量池中呢?

1.只要是双引号引起的,都会放在常量池中

我们重新分析文章开头的代码

StringTable这张表里面存放了很多的字符串对象,每个字符串对象都有hash和value,我们随便找一个地址(0x111)的字符串对象来举例

s1本身作为一个字符串对象,也有value和hash(注意value是一个数组),而s1 = “hello"

其实相当于s1的value指向hello这个对象

此时再让刚刚StringTable里0x111的字符串对象的hash指向s1的value,这样hello就可以借助s1存进常量池里了

此时又有一个s2 = "hello",遇到双引号,先去常量池查找是否有当前这个字符串,一查还真有,那就不会再把这个对象再存一遍了,那s2就可以获得常量池中hello的字符串对象的地址0x77了

🆗我们接着来看s3

因为s3的操作是new String 创建一个新对象,把这个新对象的value指向hello,所以后面会产生s1!=s3的情况

2.intern方法

    public static void main(String[] args) {
        char[] ch = new char[]{'a', 'b', 'c'};
        String s1 = new String(ch); 
        //s1.intern();
        String s2 = "abc"; 
        System.out.println(s1 == s2);
    }

先把ch和s1对象创好

new String()里面传入一个ch,我们看看源码

源码告诉我们传入东西后将这份东西再拷贝一份,s1的value引用指向拷贝出来的ch

s2的代码就是给常量池存入abc

整个流程

我们解锁s1.intern();这行代码

这行代码意思是让s1所指的对象入池,如果常量池当中存在,就不入池

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值