为什么要使用String.intern()

最近在阅读《深入理解Jav虚拟机》的运行时常量池章节,看到”java语言并不要求常量池一定只有编译器才能产生…运行期间也可以将新的常量放入常量池,这种特性被开发人员利用得比较多的时String类的intern()方法。”于是我便去深入了解了一下。

1     public static void main(String[] args) {
2         String a="王者";
3         String b="荣耀";
4         String c=a+b;             //编译期常量池不存在"王者荣耀"
5         String d=c.intern();
6         System.out.println(d==c);
7     }

上面为什么是true呢,接下来讲述intern()

为什么要使用String.intern()

JDK1.7后,intern方法先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,当字符串常量池中找不到对应的字符串时,而只是生成一个对该字符串的引用在字符串常量池。所以”王者荣耀”本身不会在字符串常量池

前面说了intern可以在程序运行时将新的常量放入运行时常量池,接下来就开始演示intern的强大用处

public static void main(String[]  args) throws Exception {
        long start=System.currentTimeMillis();   //获取开始时间
        String[] arr = new String[10000000];
        Integer[] a= new Integer[10000000];
        for (int i = 0; i < 10000000; i++) {
            a[i] = (int)(1+Math.random()*(3));
        }
        for (int i = 0; i < 10000000; i++) {
            arr[i] = new String(String.valueOf(a[i]));
        }
        long end=System.currentTimeMillis(); //获取结束时间
        System.out.println("程序运行时间: "+(end-start)+"ms");
    }
    //程序运行时间: 14461ms
public static void main(String[]  args) throws Exception {
        long start=System.currentTimeMillis();   //获取开始时间
        String[] arr = new String[10000000];
        Integer[] a= new Integer[10000000];
        for (int i = 0; i < 10000000; i++) {
            a[i] = (int)(1+Math.random()*(3));
        }
        for (int i = 0; i < 10000000; i++) {
            arr[i] = new String(String.valueOf(a[i])).intern();
        }
        long end=System.currentTimeMillis(); //获取结束时间
        System.out.println("程序运行时间: "+(end-start)+"ms");
    }
    //程序运行时间: 1688ms

就是有无调用intern方法,但程序运行时间差了10倍!

我们明确的知道,会有很多重复的相同的字符串产生,但是这些字符串的值都是只有在运行期才能确定的。所以,我们通过intern显示的将其加入运行时常量池

因为随机数是运行期才知道的,假设整个过程只产生”1″,”2″,”3″的字符串,调用了intern()就会把的堆内对象索引放入了运行常量池,下次在看见”1″,”2″,”3″,返回第一次在堆中String的对象地址,不用创建新对象,使用intern()在堆中只会创建6个对象(堆+方法区),而不使用intern则创建100000000个对象,并且常量池里并没有”1″,”2″,”3″

当在编译期知道确定了字面量,new String(“王者荣耀”).intern()没什么意义的,直接就返回了运行时字符串的地址,但intern()并不是这样的初衷,而是为了解决运行时才出现的常量,不是解决编译时在字符串常量池的问题

public class RuntimeConstantPoolOOM {
    public static void main(String[] args) {
        String str1 = new StringBuilder("计算机").append("软件").toString();
        System.out.println(str1.intern() == str1);
        //true

        String str2 = new StringBuilder("ja").append("va").toString();
        System.out.println(str2.intern() == str2);
        //flase
    }
}

最好测试字符串采取选用中文,书中有所描述,防止类加载时,默认加载类加载了字符串导致常量池中以存在真正的字面量

技术有限,如有错误,请指正,谢谢

Original: https://www.cnblogs.com/Dear-John/p/15935714.html
Author: 今晚螃蟹下酒
Title: 为什么要使用String.intern()

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/715211/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Html5+Css3BannerAnimation多方位移动特效

    背景:朋友问我小米官网的mi4的特效会做吗,可能新接的一个小网站需要用到。一直有打算研究H5C3的一些效果,趁此机会,赶紧学习一下! 效果:如图 素材 HTML: STYLE: J…

    技术杂谈 2023年7月24日
    066
  • Go基础2:数据结构(一)

    这是我参与「第三届青训营 -后端场」笔记创作活动的的第3篇笔记。 1.数组 数组是一段固定长度的连续内存区域。在Go语言中,数组从声明时就确定,使用时可以修改数组成员,但是数组大小…

    技术杂谈 2023年7月24日
    078
  • quartz框架(九)-JobRunShell

    上篇博文,博主讲了Listener相关的内容。本篇博文,博主将要详细介绍一下JobRunShell的功能。简单的来说,JobRunShell就是Job实例运行时所在的环境,也就是说…

    技术杂谈 2023年7月24日
    072
  • 一切在这里

    我们播下种子,对天空祈求,滋润植物,饮下雨水,再还给土壤,诅咒寒冷,朝着太阳跳舞,随着微风起舞,由于经历过的东西而流泪,在月亮的赔本下做梦。 我们张开我们的双手迎接另一个可能充满希…

    技术杂谈 2023年5月31日
    069
  • 18. 二叉树和二叉搜索树的最近公共祖先

    title: 二叉树和二叉搜索树的最近公共祖先 📃 题目一描述 题目链接:236. 二叉树的最近公共祖先 🔔 解题思路 思考两个节点散布在二叉树上,应该是回溯 自底向上 遍历,才会…

    技术杂谈 2023年7月24日
    073
  • 前端矩阵知识

    概述 矩阵,是线性代数中涉及的内容,线性代数在科学领域有很多应用的场景,如下: 大部分同学在大学时期应该都学过一本叫做线性代数的书,如果没猜错的话,你们的老师在教学的时候大多都是概…

    技术杂谈 2023年5月31日
    073
  • shopify主题Pacific模板配置修改

    Shopify Pacific主题一个经受住了时间考验的经典 Shopify 主题,与现有的OS 2.0兼容。使用经过验证的灵活主题建立您的业务,以帮助商店发展。非常适合 五金与汽…

    技术杂谈 2023年5月31日
    0157
  • find prune

    如果想查找某目录下的某些文件,但是想要避开某个目录,使用find 的-prune 但是-prune用法很严格,网上有很多文章介绍了它的用法,但是经过本人的实际使用,有些并不好用。 …

    技术杂谈 2023年6月1日
    0111
  • 【软考】易错选择题

    1.第01题:2018下半年系统集成项目管理工程师 工业和信息化部会同国务院有关部门编制的《信息化发展规划》提出了我国未来信息化发展指导思想和基本原则。其中,不包括( )原则。A:…

    技术杂谈 2023年5月31日
    089
  • 《睡在天堂的爱》作者:如意

    一天,父亲开口跟我要钱了。最初的借口是身体不太好,要去医院做个全身检查,我便给他寄了钱。 没想到时间不长,他又来了电话,说想买个电动三轮车。我犹豫了一下,他好像听出我的迟疑,说:&…

    技术杂谈 2023年6月1日
    094
  • 编程语言居然是魔法咒语!

    作为一个本职是程序员的魔幻爱好人士,THE DAY,我终于意识到了! 如果你不懂魔法的麻瓜,没关系,让我一点点来揭开这个世纪大奥妙。 首先我们从最简单的HTML 开始,这个在技术上…

    技术杂谈 2023年6月21日
    0117
  • Arrays.sort(arr)是什么排序

    当数组长度大于286时 此时回到那段很长很长的代码段,在判断小于286的长度数组之后,从注解中: // Check if the array is nearly sorted 这里…

    技术杂谈 2023年7月24日
    061
  • 手把手教你:人脸识别考勤系统

    系列文章 手把手教你:人脸识别考勤系统 本文为系列第一篇 @ 系列文章 项目简介 一、项目展示 二、环境需求 环境安装实例 三、功能模块介绍 1.人脸库图像 2.构建人脸库 3.启…

    技术杂谈 2023年7月25日
    070
  • Map接口总结(如何使用默认方法)

    default方法 排序在前的方法较为常用。 默认方法是为了在标准库中添加默认支持函数式方法,同时也不必修改现有的类,这样做虽然有一定的好处,但是实际上在子类中使用default方…

    技术杂谈 2023年7月24日
    075
  • dstat命令详解

    dstat命令详解 -c,–cpu 开启cpu统计 -d, –disk 开启disk统计 -D 改选跟具体的设备名(多个用逗号隔开)如:total,hda,…

    技术杂谈 2023年5月31日
    0118
  • 动态ip、静态ip、pppoe拨号的区别

    pppoe拨号 pppoe拨号上网,又叫做ADSL拨号上网、宽带拨号上网。指现在有很多我的E家用户,送的无线猫,阉割了PPPOE拨号功能,必须要从电脑上拨号才能上网。还有大街上的W…

    技术杂谈 2023年5月31日
    0102
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球