了解intern(),了解字符串常量池

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/mryang125/article/details/83752132

intern()是String一个api,平时不常用,但是面试可能会考,掌握intern可避免被面试官问到时大眼瞪小眼的尴尬局面。

当一个String对象调用intern()方法时,会首先检查字符串常量池中是否存在equals相等的字符串,若存在直接返回常量池中该字符串对象,否则创建该字符串对象并放入字符串常量池。

然而并不是所有创建的字符串都会进入常量池。下面直接贴代码,每行代码都通过备注的形式给出了运行结果和相关解释。

          String a = new String("ab"); //开辟新的堆内存,存放字符串对象"ab",引用为 a,同时"ab"进入字符串常量池
          String b = new String("ab"); //开辟新的堆内存,存放字符串对象"ab",引用为 b,同时"ab"指向字符串常量池已有的对象
          String c = "ab"; //未开辟新的堆内存,直接将引用c指向了字符串常量池已有的"ab" 
          String d = "a" + "b"; //通过拼接静态字符串的方式先检查常量池中是否已有相等的对象,有则直接将引用指向和c相同的对象
          String e = "b"; //引用e指向一个新的字符串
          String f = "a" + e; //和e拼接将产生一个新的对象,即f指向新的内存地址
          
          System.out.println(c == d); //true  //d通过+拼接的是静态字符串,非引用
          System.out.println(f == d); //false //f通过+拼接了一个引用相当于新创建了一个对象。
          
          //通过new 创建的字符串对象(a本身,b本身)不会进入字符串常量池
          System.out.println(a == a.intern()); //false,a没有进入常量池,但是a.intern()已经进入,二者非同一对象
          System.out.println(c == c.intern()); //true,c本来就在字符串常量池,所以返回true
          System.out.println(b.intern() == a); //false,a没有进入常量池,但是b.intern()已经进入且和a.intern()是同一个对象
          System.out.println(b.intern() == c); //true, b.intern()进入了常量池,c和该池子中的对象
          
          //通过+拼接静态字符串得到的字符串对象会进入字符串常量池
          System.out.println(b.intern() == d); //true
          
          //非静态字符串通过+拼接不会进入字符串常量池
          System.out.println(b.intern() == f); //false

          System.out.println(b.intern() == a.intern()); //true

大体总结3点:

1.new String的方式创建字符串对象,构造器参数进入字符串常量池,但是对象本身和常量池中的对象是两个不同的对象。从而导致这种方式产生的字符串调用intern()方法和本身引用 == 将返回false。

2.静态声明的方式定义的字符串直接进入字符串常量池,如常量池已有该字符串,则直接指向已有字符串。这种方式产生的字符串调用intern()方法和本身引用==始终返回true。

3.+拼接静态字符串创建的对象会进入字符串常量池,但是+拼接字符串引用就不会进入常量池。二者会导致完全不同的结果,前者调用intern()和自身==返回true,后者调用intern()和自身==返回false。

 

展开阅读全文

没有更多推荐了,返回首页