zoukankan      html  css  js  c++  java
  • String.intern方法

    参考连接:https://www.jianshu.com/p/be66e22f5fc8      可以联系我删除本博客

      我们知道再jvm的运行时内存可以分为堆、方法区、程序计数器、虚拟机栈和本地方法栈。而在方法区中有一个字符串常量池,用来保存字符串这个不可变量。如果我们使用String str=new String("java虚拟机")来new一个string对象,则该对象的实例保存在堆中。如果我们使用String str="java虚拟机"来创建一个字符串,jvm首先会在字符串常量池中创建该String的实例,然后将常量池中该实例的引用返回给str。
    new出来的String保存在堆中,如果我们想让字符串常量池中也保存该string的实例呢?可以使用String.intern()这个方法将字符串复制到常量池中,返回在常量池中的引用。

      但是在jdk1.7以后,使用String.intern()方法和之前有一些不同。intern方法还是会先去查询常量池中是否有已经存在,如果存在,则返回常量池中的引用,这一点与之前没有区别,区别在于,如果在常量池找不到对应的字符串,则不会再将字符串拷贝到常量池,而只是在常量池中生成一个对原字符串的引用。简单的说,就是往常量池放的东西变了:原来在常量池中找不到时,复制一个副本放到常量池,1.7后则是将在堆上的地址引用复制到常量池。

    当然这个时候,常量池被从方法区中移出来到了堆中。


    我们看一下如下的代码

        public static void main(String[] args) {
            String str1=new StringBuilder("java").append("虚拟机").toString();//执行完这行代码后,常量池中会有"java"和"虚拟机",但是不会有"java虚拟机"。
            System.out.println(str1.intern()==str1);
            String str2=new String("我喜欢java");  //执行完这行代码后,常量池中会有"我喜欢java"
            System.out.println(str2==str2.intern());

    true
    false

    分析

    str1指向的实例是在堆中,是由“java”和"虚拟机"拼接成的。执行完第一句代码后,执行完这句话后,常量池中会有"java"和"虚拟机",但是不会有"java虚拟机"。然后使用str1.intern()会在常量池中保存str1实例的引用,并且返回引用,因此str1.intern()==str1。
    而执行完String str2=new String("我喜欢java");后,常量池中会有"我喜欢java",所以在使用str2.intern()返回的就是字符串常量池中的引用,而str2指向的是堆中的引用,因此str2!=str2.intern()。




     



  • 相关阅读:
    cocos2dx的MotionStreak.cpp解析(-)
    gcc/g++基本命令简介
    C++编译器与链接器工作原理
    简单介绍 ARC 以及 ARC 实现的原理
    求两个链表表示的数的和
    对象内存结构中的 isa 指针是用来做什么的?
    按层遍历二叉树的节点
    一个 Objective-C 对象的内存结构是怎样的?
    创建一个可以被取消执行的 block
    TCP&UDP
  • 原文地址:https://www.cnblogs.com/shuai666/p/14749740.html
Copyright © 2011-2022 走看看