String 在 java 中是一个使用最频繁的类,也是占据内存最大的类,合理的优化 String 对象,能够节省宝贵的内存资源。java
在每次赋值的时候使用,若是常量池中有相同值,就会重复使用该对象,返回对象引用,这样一开始的对象就能够被回收掉。数组
上一段代码优化
String s1 = "abc"; String s2 = new String("abc"); String s3 = s2.intern(); System.out.println("1:" + (s1 == s2)); System.out.println("2:" + (s2 == s3)); System.out.println("3:" + (s1 == s3)); System.out.println("================================"); String s4 = new String("1") + new String("1"); String s5 = "11"; System.out.println("4:" + (s4 == s5)); String s6 = s4.intern(); System.out.println("5:" + (s4 == s5)); System.out.println("6:" + (s5 == s6)); System.out.println("7:" + (s4 == s6));
结果是:指针
1:false 2:false 3:true ================================ 4:false 5:false 6:true 7:false
理解这一块的核心在于这段代码运行是分为2个阶段的,1.类加载 2.类执行
code
1.类加载时(注:JDK 1.7 以后,常量池合并在堆中):对象
2.类运行时:在堆内存中开辟一个空间存放该对象,String 类中的 char 数组引用常量池对象,返回堆内存中的地址给变量引用。内存
若是调用 intern() 方法,就会去字符串常量池中查看是否有等于该对象字符串的引用,若是有,就返回返回字符串常量池中的引用
。资源
额外注意 s4 动态生成的字符串
动态生成的字符串直接在堆上建立,字符串常量池没有,当调用 intern 方法获取引用时,则会去常量池中判断是否有相等的引用,若是有返回引用,若是没有则放入。字符串
intern 方法 不改版自己的指针引用
,从7就能够看出,s4调用intern 后与 s6 比较,仍不相等。变量
非动态生成的字符串,在类加载时就已经将字符串对象放入常量池中,运行时视对象是常量仍是变量赋值:
intern 方法,若是常量池中没有匹配的字符串,就将本身放入而后返回,不然返回字符串对象在常量池中的地址。
为何相等 ?
String a =new String("abc").intern(); String b = new String("abc").intern(); if(a==b) { System.out.print("a==b");}