zoukankan      html  css  js  c++  java
  • Java 字符串常量池 及 intern 方法的使用

     参考这篇文章:深入解析String#intern - 美团技术团队 (meituan.com)

    jdk7 版本对 intern 操作和常量池都做了一定的修改,主要包括2点:

    1. 将String常量池 从 Perm 区移动到了 Java Heap区
    2. String#intern 方法时,如果存在堆中的对象,会直接保存堆中对象的引用,而不会重新创建对象

    下面做一个测试:

     1 public static void main(String[] args) {
     2 
     3         /*
     4          * new String("a") + new String("b") 在堆和字符串常量池一共传创建了 5 个对象,分别为:
     5          * 堆:"a"、"b"、"ab" + 字符串常量池:"a"、"b"
     6          * 但 str1 是堆中 "ab" 对象的引用,并非字符串常量池 "ab" 对象的引用
     7          * str1.intern() 实际是返回了字符串常量池 "ab" 对象的引用
     8          * str3.intern() 也是返回了字符串常量池 "ab" 对象的引用
     9          */
    10 
    11         // 返回堆中 "ab" 对象的引用
    12         String str1 = new String("a") + new String("b");
    13         // 在字符串常量池中生成 "ab" 对象并返回其引用
    14         String str2 = "ab";
    15         // 返回堆中新生成的 "ab" 对象的引用
    16         String str3 = new String("a") + new String("b");
    17         // false, str1.intern() 返回字符串常量池中的引用,str1为堆中的引用,二者不是同一个内存地址
    18         System.out.println(str1.intern() == str1);
    19         // true, str1.intern() 和 str2 都是堆中同一个对象 "ab" 的引用
    20         System.out.println(str1.intern() == str2);
    21         // false, str1 和 str3 分别指向了堆中 2 个不同的 "ab" 对象
    22         System.out.println(str1 == str3);
    23         // true, str1.intern() 和 str3.intern() 都是字符串常量池中同一个对象 "ab" 的引用
    24         System.out.println(str1.intern() == str3.intern());
    25     }

     另一个测试:

     1     public static void main(String[] args) {
     2         /*
     3          * 直接使用双引号声明出来的 String 对象会直接存储在常量池中,此时堆中生成一个 ”1“ 对象,字符串常量池中也生成一个 ”1“ 对象
     4          * 返回的是堆中 ”1“ 对象的引用
     5          */
     6         String s = new String("1");
     7         // 此时字符串常量池中已经存在 ”1“ 对象了,所以不会有堆中此对象引用拷贝的操作了
     8         s.intern();
     9         // 此时字符串常量池中已经存在 ”1“ 对象了,直接返回字符串常量池中此对象的引用
    10         String s2 = "1";
    11         // fasle, s 为堆中对象的引用,s2 为字符串常量池中对象的引用,二者内存地址不一样
    12         System.out.println(s == s2);
    13 
    14         // 在堆中生成 3 个对象,分别为 ”1“、”1“、”11“ 并返回堆中对象 ”11“ 的引用,此时常量池中是没有 ”11“ 对象的
    15         String s3 = new String("1") + new String("1");
    16         // 把 s3 的引用拷贝到字符串常量池中
    17         s3.intern();
    18         // 直接返回字符串常量池中 s3 的引用
    19         String s4 = "11";
    20         // true,s3 和 s4 均为字符串常量池中的同一个内存地址
    21         System.out.println(s3 == s4);
    22     }
  • 相关阅读:
    python:使用 watchdog 监控文件变化
    CSS 宽高度百分比加减像素的办法
    foxmail登陆失败LOGIN Login error user suspended
    IDEA 自动删除类中无用的import包
    CSS命名规范——BEM思想
    jQuery文件上传插件 uploadify 的使用
    textarea 固定大小,滚动条,限制拖动,文字对齐等
    命令行工具 Cmder 的使用与配置
    转:【MySQL】连接错误过多:is blocked because of many connection errors; unblock with 'mysqladmin flush-host
    OpenJFX的相关Maven依赖
  • 原文地址:https://www.cnblogs.com/frankyou/p/15047640.html
Copyright © 2011-2022 走看看