zoukankan      html  css  js  c++  java
  • [java基础][字符串]由字符串常量池引发的思考

    最近在回头看java基础这块,遇到一段比较有意思的代码

    @Test
    public void testIntern(){
    String s1 = new String("helloworld"); // 堆
    String s2 = "helloworld"; //堆中的字符串常量池中
    String intern1 = s1.intern(); //internl引用s1的堆对象
    System.out.println(s1 == s2); //false
    String s3 = new String("helloyeah");       //堆 与 字符串常量池 S3是堆的引用
    String intern3 = s3.intern(); //intern3是字符串常量池中引用s3的堆对象
    String s4 = "helloyeah"; //字符串常量池里已经有了 helloyeah,所以直接返回这个引用
    System.out.println(s3 == s4); //false
    System.out.println(intern3 == s4); //true 二者引用的同一个常量
    String s5=new String("hello")+new String("yeah"); //堆
    System.out.println(s5==s3); //false
    String intern5=s5.intern(); // 去常量去查是否有"helloyeah"常量池,发现已经有了s3.intern()的的这个。
    System.out.println(intern5==intern3); //true 因为引用相同
    System.out.println(intern5==s4); //true 因为引用相同
    String s6="helloyeah"; //字符串常量池
    System.out.println(s5==s6); //false
    String s7=new String("hello")+new String("yeah0"); //堆
    String intern7=s7.intern(); //intern7是字符串常量池中引用s7的堆对象
        String s8="helloyeah0";                             //判断常量池中是否有这个字面量是否已经存在引用,发现s7已经有了,则返回intern7
    System.out.println(s7==s8);//true
    System.out.println(intern7==s8);//true

    }

    这段代码是来自一篇博文的评论区,本来看完这篇文章,跑了跑代码,感觉没有啥问题,但是看到评论区的时候,发现自己对这块理解的还是有问题。大家可以先想一下上面代码每一次的结果是什么?

    https://tech.meituan.com/2014/03/06/in-depth-understanding-string-intern.html这篇文章里说的比较清楚,好好看看

    主要就是java7之后,由于字符串常量池从原来的perm space挪到了 heap 区,对intern方法的改变。最大的区别就是java7之后,intern操作后,建立的是一个一个引用,如果字面量字符串存在,则直接引用,如果不存在,则引用的是堆里的对象。

    2019-07-13

    今天阅读 深入java虚拟机 里提到了这块常量池,文中给出了一个有趣的例子,以及一个简单的判断的方法

     1     @Test
     2     public void testConstantPoolOOM(){
     3         String str2=new StringBuilder("ja").append("va").toString();
     4         System.out.println(str2.intern()==str2);
     5         String str3=new StringBuilder("ja1").append("va").toString();
     6         System.out.println(str3.intern()==str3);
     7         String str4=new StringBuilder("jav").append("a").toString();
     8         System.out.println(str4.intern()==str4);
     9         System.out.println(str2==str4);
    10         System.out.println(str4.intern()==str2.intern());
    11         String str1=new StringBuilder("计算机").append("234").toString();
    12         System.out.println(str1.intern()==str1);
    13     }

    有趣,是"java"这个字符串为什么会提前在常量池里存在了,简单的判断方法就是判断,常量池里是否首次出现这个字符串,如果是首次,则建立一个引用关系,如果不是首次,则会返回之前引用的引用。

  • 相关阅读:
    大整数模拟
    MSSQL存储过程中获取记录集并循环操作一例
    about协议的妙用
    C#基础概念二十五问
    很完美的JS判断日期函数
    asp.net C# FileUpload 控件如何判断文件名的后缀
    c++中指针学习的两个绝好例子
    ASP.net性能优化总结
    C++指针
    JS中的undefined,null,"",0和false
  • 原文地址:https://www.cnblogs.com/lifetraveler/p/11176009.html
Copyright © 2011-2022 走看看