String常量池理解

 * @author  Lee Boynton
 * @author  Arthur van Hoff
 * @version %I%, %G%
 * @see     java.lang.Object#toString()
 * @see     java.lang.StringBuffer
 * @see     java.lang.StringBuilder
 * @see     java.nio.charset.Charset
 * @since   JDK1.0
 */

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
{
    /** The value is used for character storage. */
    private final char value[];

    /** The offset is the first index of the storage that is used. */
    private final int offset;

    /** The count is the number of characters in the String. */
    private final int count;

    /** Cache the hash code for the string */
    private int hash; // Default to 0


Sring使用 final char value[ ] 存储字符串内容。即当一个String对象创建完毕后,该对象值已不可修改。故String被称为不可变类型。

String常量池:虚拟机中类似一张全局String列表,其中元素唯一,使用“”双引号创建String对象将保存于常量池,此方式创建对象时先检查常量池中是否存在该字符串对象,存在返回引用,不存在创建再返回。用于提高效率。

String对象两种创建方式:
1, new String(“abcd”):此处创建两个String对象:new String(),"abcd" ,前者存储于堆内存,后者存于常量池(见下测试1)。
2,“abcd”: 直接使用双引号创建String对象保存于字符串常量池。


String对于+运算符的重载:
1: “ab”+"cd"
String s1 = "ab" + "cd";
String s2 = "abcd";
syso(s1 == s2);
print: true;
此方式生成第三个字符串"abcd",存于常量池。
2: 

String s1 = "ab"; 
String s2 = s1 + "cd";
syso(s2.intern() == s2);
print:  false  
此方式生成字符串存在于堆内存;


测试1: new String("Demo"), 参数字符串存储于常量池 or 堆内存?

修改String源码如下
注:intern()方法:查找常量池中是否有相同字符串常量,有则返回其引用,没有则在常量池中创建新String并返回引用。
编译class,覆盖rt.jar文件。

public String(String original) {
    	
    String tmp = original.intern();
    System.out.println(tmp == original? "存于常量池" : "未存于常量池");
	int size = original.count;
	char[] originalValue = original.value;
	char[] v;
  	if (originalValue.length > size) {
 	    // The array representing the String is bigger than the new
 	    // String itself.  Perhaps this constructor is being called
 	    // in order to trim the baggage, so make a copy of the array.
            int off = original.offset;
            v = Arrays.copyOfRange(originalValue, off, off+size);
 	} else {
 	    // The array representing the String is the same
 	    // size as the String, so no point in making a copy.
	    v = originalValue;
 	}
	this.offset = 0;
	this.count = size;
	this.value = v;
    }
	
测试代码:

public class StringDemo {
	public static void main(String[] args) {
		new String("haha");
	}
}
结果打印:存于常量池


StringBuilder,StringBuffer效率提高在哪:
这两个类维护非final字符数组,用于连续添增字符拼接,避免了使用String类型+运算符生成很多多余无用的String对象.且字符串常量池常驻内存,生命周期较长,故节省内存了开支。但append(String)方法中 并没有避免参数String对象的创建.且此处String对象存储于常量池。 


新手,有错误请指教。谢谢。

whanche@126.com 欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值