StringPool的底层原理深度剖析以及关键问题阐述(简单实现StringPool)

本文探讨了Java中的StringPool原理,强调了其在内存管理中的作用,特别是如何避免重复String对象的创建。文章详细解释了intern方法的工作机制,指出其用于将字符串添加到字符串常量池以节省内存资源。作者还解答了关于StringTable实现的问题,讨论了为何使用WeakReference以及何时加载字符串到堆中。最后,通过代码示例展示了StringPool如何在查找相同字符串时提供内存地址。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引用就是堆空间的内存首地址。==的作用就是比较首地址。String中的数组是final所以是不可分割的。

1.java7使用intern方法时,如果常量池中不存在该字符串,那么字符串常量池里面保存的是堆中对象;当常量池存在的时候,那么intern返回的就是常量池中保存的引用,如何实现字符串常量池的不可重复性?

答:

(1)两种情况StringTable保存的都是String的引用,对象仍然创建在堆空间中,只不过在java7之后   不会重复生成对象了。

(2)StringTable中的key就是不重复的,所以石祥路字符串常量的不可重复。

2.为什么要使用intern方法?intern方法结果是什么?intern方法如何实现的?

答:

(1)利用intern方法使运行中的进程可以将字符串添加到字符串常量池(因为一个进程的堆中30%空间存储的都是String对象,同时14.5%的String对象还是重复的,这个时候使用intern就可减少内存资源浪费)

(2)intern就是将字符串的引用放到字符串常量池中

(3)通过StringTable中的WeakReference实现的

3.StringTable如何实现的?Map<String,WeakReference>为什么使用Reference找到已经存在key值?可以不使用Reference找到key值?

答:(1)如果不使用Reference那么就需要遍历集合,时间复杂度很高。

4.“1”是在什么时候加载到堆中的。

答:(1)在加载有“1”的class文件的时候就会加载。

关键提示:首先要明白HashTable添加元素比较的是hashcode()和equals()返回的值,这个和内存首地址概念是不同的。

通过下列代码感受一下Pool的作用:就是为了第二次寻找相同的字符串的时候返回第一次已经存在的字符串的内存地址。

public class TestPool {
    final static Map<String,String> pool = new HashMap<>(1024);
    public static void main(String[] args) {
//        不使用reference查找已经存在的字符串
        String first00 = new String("0") + new String("0");
        String second00 = "00";
//      发现first00 和 second00的内存首地址是不一致的所有返回false
        System.out.println(first00 == second00);
//        如何根据second00的内存首地址找到first00的内存首地址,这里的方法就是没有使用reference。
        String first = myintern(first00);
        String second = myintern(second00);
        System.out.println(first == second);
//        使用StringTable中的reference实现了唯一性。
        String table1 = StringTable.intern(first00);
        String table2 = StringTable.intern(second00);
        System.out.println(table1==table2);

    }

//    没有使用value值,仅仅根据key的遍历找到了最开始的String值,时间复杂度高。
    public static String myintern(String str){
        Set<String> arr = pool.keySet();
        for(String s : arr){
            if(s.equals(str)){
                return s;
            }
        }
        pool.put(str,null);
        return str;
    }
}
public class StringTable {
    private static final Map<String, WeakReference<String>> pool = new HashMap<>(1009);
    public static String intern(String str){
        WeakReference<String> weakReference = pool.get(str);
        if(weakReference!=null){
            String res = weakReference.get();
            if(res != null){
                return res;
            }
        }
        pool.put(str,new WeakReference<String>(str));
        return str;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值