String的底层机制

1.源码

●初始化

public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
	private final char value[];
	public String(){
		this.value = new char[0];
	}	
}

可以看见String类和属性值被声明为final,不可被修改。本质上是一个字符数组。
●实例化

public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

●查找某个位置的字符

public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
}

●判断两个字符串是否相等

public boolean equals(Object anObject){
	if(this == anObject){
		return true;
	}
	if(anObject instanceof String){
		String anotherString = (String)anObject;
		int n = value.length;
		if(n == anotherString.value.length){
			char v1[] = value;
			char v2[] = anotherString.value;
			int i=0;
			while(n--!=0){
				if(v1[i]!=v2[i])
					return false;
				i++;
			}
			return true;
		}
	}
	return false;
}
--------重写equals()同时也必须重写hashCode()----------
public int hashCode(){
	int h = hash;
	if(h == 0 && value.length>0){
		char val[] = value;
		for(int i=0;i<value.length;i++){
			h = 31*h+val[i];
		}
		hash = h;
	}
	return h;
}

2.JVM内存原理

Java虚拟机主要管理两种内存:堆和非堆。
堆是指运行时数据区域,在虚拟机启动时创建并所有线程共享。几乎所有对象实例及数组都在堆内分配,因此堆也是垃圾收集器的主要作用区域。
我们平时说的内存就是运行时数据区
1.方法区:存储类信息、常量、静态变量(全局共享)
2.堆:存放对象和数组(全局共享)
3.栈:基本数据类型、对象的引用(地址信息),线程私有。
Java内存模型
在这里插入图片描述
String有两种赋值方式:
1.字面量赋值 String str = “hello”
2.new关键字 String str = new String(“hello”)
他们的区别:
字面量赋值
当主线程开始创建str变量的,虚拟机会去字符串池中找是否有equals(“Hello”)的String,如果相等就把在字符串池中“Hello”的引用复制给str。如果找不到相等的字符串,就会在堆中新建一个对象,同时把引用驻留在字符串池,再把引用赋给str。当用字面量赋值的方法创建字符串时,无论创建多少次,只要字符串的值相同,它们所指向的都是堆中的同一个对象。
new对象
当利用new关键字去创建字符串时,前面加载的过程是一样的,只是在运行时无论字符串池中有没有与当前值相等的对象引用,都会在堆中新开辟一块内存,创建一个对象

由于不同版本的JDK内存会有些变化,JDK1.6字符串常量池在永久代,1.7移到了堆中,1.8用元空间代替了永久代。但是基本对上面的结论没有影响,思想是一样的。

补充

String是不可变类,任何对String对象的修改都会生成新的String对象。

如对原字符串进行拼接:
jdk1.8之后字符串拼接底层就是创建了一个StringBuilder,然后调用append方法,最后调用toString转化成String
个人分析:
若底层采用字符数组动态地在末尾添加的方法,每添加一个字符都会创建一个新的String对象,极浪费空间,而采用StringBuilder方式则不会造成空间浪费,且效率更优。
因此,如果遇到大量的字符串拼接操作,我们还是采用StringBuilder/StringBuffer操作效率更高。

参考链接
如有不对敬请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值