String类的零碎知识点

来源:互联网 发布:ecshop 2.7.3 php版本 编辑:程序博客网 时间:2024/06/09 20:59

String类的零碎知识点

1、关于==和equals

前者是引用一致判断,对内存中引用对象的比较,如果两个对象指向了同一个内存空间(或叫内存地址,封装一下叫引用对象),则返回true;

后者是自定义的比较,如果不重写equals默认和==一样,但是后者可以通过改写hashcode和equals方法来实现自定义比较;

相比==,equals更注重内容一致性判断;

对于==返回ture的,equals一定返回true;反之则不一定。

2、对于String类的赋值:new String(“abc”)&& “abc”

String str1 = new String(“abc”);   String str2 = “abc”;String str3 = new String(“abc”);String str4 = “abc”;String str5 = “ab”+”c”;
  • 对于str1,虚拟机直接在堆区创建一个对象,然后让str1指向该对象;
  • 对于str2,虚拟机先去String Pool里寻找是否存在和“abc”相等的字符串对象,如果有,则将str2指向String pool中的字符串地址;
  • 对于str3,虚拟机直接在堆区创建一个对象,虽然str1已经创建了一个内容相同的对象,但是str4还是会创建一个对象,所以str1==str4返回false,因为他们指向了不同的对象;
  • 对于str4,虚拟机会先去String pool寻找与“abc”内容相同的对象,发现存在了(如果之前没有,str2也创建了),所以str4就直接指向了String Pool中的“abc”,所以str2==str4返回true;
  • 对于str5,会将字符串先进行表达式计算,然后放入字符串池中,即str2==str5返回true;
String ab = “ab”;String c = “c”;
  • 对于变量的拼接或者变量和常量的拼接(ab+“c”),String类会按照new一个字符串的方式在堆区创建一个对象,即ab+c==str2返回false;

3、 对于String类的intern方法

String str6 = str1.intern();
  • Intern方法会返回一个将str1放入String Pool的指针(如果池中没有,则加入),此时str2==str6会返回true;
  • 但是intern方法并不会改变str1的指针,即str1==str2依然返回false;
  • 该方法的实现是一个本地(native)方法;

4、String Pool

  • 对于字符串池,一般来说,当一个字符串进入到字符串池中,如果没有了外部引用,也不会被垃圾回收,因为字符串池不会被垃圾回收,所以这样可能会导致内存泄漏;
  • 在虚拟机中,这一块称为String常量池的区间专门用于存放字符串常量。在JDK 1.6之前,这块区间属于永久区的一部分,但是在JDK 1.7以后,它就被移到了堆中进行管理。
  • 可以通过以下代码测试:
public static void main(String[] args) {          List<String> list = new ArrayList<String>();          int i = 0;          while(true){              list.add(String.valueOf(i++).intern());          }      }  //JVM参数设置为:-Xmx5m -XX:MaxPermSize=5m
  • 当JDK版本大于1.7的时候,会报错:java.lang.OutOfMemoryError: Java heap space
  • 而低于1.7的则会报错:java.lang.OutOfMemoryError: PermGen space  
原创粉丝点击